Code Coverage

Cobertura Coverage Report > osmclient.sol005 >

nst.py

Trend

File Coverage summary

NameClassesLinesConditionals
nst.py
100%
1/1
16%
20/127
100%
0/0

Coverage Breakdown by Class

NameLinesConditionals
nst.py
16%
20/127
N/A

Source

osmclient/sol005/nst.py
1 # Copyright 2018 Telefonica
2 #
3 # All Rights Reserved.
4 #
5 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
6 #    not use this file except in compliance with the License. You may obtain
7 #    a copy of the License at
8 #
9 #         http://www.apache.org/licenses/LICENSE-2.0
10 #
11 #    Unless required by applicable law or agreed to in writing, software
12 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 #    License for the specific language governing permissions and limitations
15 #    under the License.
16
17 1 """
18 OSM NST (Network Slice Template) API handling
19 """
20
21 1 from osmclient.common.exceptions import NotFound
22 1 from osmclient.common.exceptions import ClientException
23 1 from osmclient.common import utils
24 1 import json
25 1 import magic
26 1 import logging
27 1 import os.path
28
29 # from os import stat
30 # from os.path import basename
31
32
33 1 class Nst(object):
34 1     def __init__(self, http=None, client=None):
35 0         self._http = http
36 0         self._client = client
37 0         self._logger = logging.getLogger("osmclient")
38 0         self._apiName = "/nst"
39 0         self._apiVersion = "/v1"
40 0         self._apiResource = "/netslice_templates"
41 0         self._apiBase = "{}{}{}".format(
42             self._apiName, self._apiVersion, self._apiResource
43         )
44
45 1     def list(self, filter=None):
46 0         self._logger.debug("")
47 0         self._client.get_token()
48 0         filter_string = ""
49 0         if filter:
50 0             filter_string = "?{}".format(filter)
51 0         _, resp = self._http.get2_cmd("{}{}".format(self._apiBase, filter_string))
52         # print(yaml.safe_dump(resp))
53 0         if resp:
54 0             return json.loads(resp)
55 0         return list()
56
57 1     def get(self, name):
58 0         self._logger.debug("")
59 0         self._client.get_token()
60 0         if utils.validate_uuid4(name):
61 0             for nst in self.list():
62 0                 if name == nst["_id"]:
63 0                     return nst
64         else:
65 0             for nst in self.list():
66 0                 if "name" in nst and name == nst["name"]:
67 0                     return nst
68 0         raise NotFound("nst {} not found".format(name))
69
70 1     def get_individual(self, name):
71 0         self._logger.debug("")
72 0         nst = self.get(name)
73         # It is redundant, since the previous one already gets the whole nstinfo
74         # The only difference is that a different primitive is exercised
75 0         try:
76 0             _, resp = self._http.get2_cmd("{}/{}".format(self._apiBase, nst["_id"]))
77             # print(yaml.safe_dump(resp))
78 0             if resp:
79 0                 return json.loads(resp)
80 0         except NotFound:
81 0             raise NotFound("nst '{}' not found".format(name))
82 0         raise NotFound("nst '{}' not found".format(name))
83
84 1     def get_thing(self, name, thing, filename):
85 0         self._logger.debug("")
86 0         nst = self.get(name)
87 0         headers = self._client._headers
88 0         headers["Accept"] = "application/binary"
89 0         try:
90 0             http_code, resp = self._http.get2_cmd(
91                 "{}/{}/{}".format(self._apiBase, nst["_id"], thing)
92             )
93 0         except NotFound:
94 0             raise NotFound("nst '{} 'not found".format(name))
95         # print('HTTP CODE: {}'.format(http_code))
96         # print('RESP: {}'.format(resp))
97         # if http_code in (200, 201, 202, 204):
98 0         if resp:
99             # store in a file
100 0             return json.loads(resp)
101         # else:
102         #    msg = ""
103         #    if resp:
104         #        try:
105         #            msg = json.loads(resp)
106         #        except ValueError:
107         #            msg = resp
108         #    raise ClientException("failed to get {} from {} - {}".format(thing, name, msg))
109
110 1     def get_descriptor(self, name, filename):
111 0         self._logger.debug("")
112 0         self.get_thing(name, "nst", filename)
113
114 1     def get_package(self, name, filename):
115 0         self._logger.debug("")
116 0         self.get_thing(name, "nst_content", filename)
117
118 1     def get_artifact(self, name, artifact, filename):
119 0         self._logger.debug("")
120 0         self.get_thing(name, "artifacts/{}".format(artifact), filename)
121
122 1     def delete(self, name, force=False):
123 0         self._logger.debug("")
124 0         nst = self.get(name)
125 0         querystring = ""
126 0         if force:
127 0             querystring = "?FORCE=True"
128 0         http_code, resp = self._http.delete_cmd(
129             "{}/{}{}".format(self._apiBase, nst["_id"], querystring)
130         )
131         # print('HTTP CODE: {}'.format(http_code))
132         # print('RESP: {}'.format(resp))
133 0         if http_code == 202:
134 0             print("Deletion in progress")
135 0         elif http_code == 204:
136 0             print("Deleted")
137         else:
138 0             msg = resp or ""
139             # if resp:
140             #     try:
141             #         resp = json.loads(resp)
142             #     except ValueError:
143             #         msg = resp
144 0             raise ClientException("failed to delete nst {} - {}".format(name, msg))
145
146 1     def create(self, filename, overwrite=None, update_endpoint=None):
147 0         self._logger.debug("")
148 0         if os.path.isdir(filename):
149 0             charm_folder = filename.rstrip("/")
150 0             for files in os.listdir(charm_folder):
151 0                 if "nst.yaml" in files:
152 0                     results = self._client.package_tool.validate(
153                         charm_folder, recursive=False
154                     )
155 0                     for result in results:
156 0                         if result["valid"] != "OK":
157 0                             raise ClientException(
158                                 "There was an error validating the file: {} "
159                                 "with error: {}".format(result["path"], result["error"])
160                             )
161 0             result = self._client.package_tool.build(charm_folder)
162 0             if "Created" in result:
163 0                 filename = "{}.tar.gz".format(charm_folder)
164             else:
165 0                 raise ClientException(
166                     "Failed in {}tar.gz creation".format(charm_folder)
167                 )
168 0             self.create(filename, overwrite, update_endpoint)
169         else:
170 0             self._client.get_token()
171 0             mime_type = magic.from_file(filename, mime=True)
172 0             if mime_type is None:
173 0                 raise ClientException(
174                     "Unexpected MIME type for file {}: MIME type {}".format(
175                         filename, mime_type
176                     )
177                 )
178 0             headers = self._client._headers
179 0             if mime_type in ["application/yaml", "text/plain"]:
180 0                 headers["Content-Type"] = "application/yaml"
181 0             elif mime_type in ["application/gzip", "application/x-gzip"]:
182 0                 headers["Content-Type"] = "application/gzip"
183                 # headers['Content-Type'] = 'application/binary'
184                 # Next three lines are to be removed in next version
185                 # headers['Content-Filename'] = basename(filename)
186                 # file_size = stat(filename).st_size
187                 # headers['Content-Range'] = 'bytes 0-{}/{}'.format(file_size - 1, file_size)
188             else:
189 0                 raise ClientException(
190                     "Unexpected MIME type for file {}: MIME type {}".format(
191                         filename, mime_type
192                     )
193                 )
194 0             headers["Content-File-MD5"] = utils.md5(filename)
195 0             self._http.set_http_header(headers)
196 0             if update_endpoint:
197 0                 http_code, resp = self._http.put_cmd(
198                     endpoint=update_endpoint, filename=filename
199                 )
200             else:
201 0                 ow_string = ""
202 0                 if overwrite:
203 0                     ow_string = "?{}".format(overwrite)
204 0                 self._apiResource = "/netslice_templates_content"
205 0                 self._apiBase = "{}{}{}".format(
206                     self._apiName, self._apiVersion, self._apiResource
207                 )
208 0                 endpoint = "{}{}".format(self._apiBase, ow_string)
209 0                 http_code, resp = self._http.post_cmd(
210                     endpoint=endpoint, filename=filename
211                 )
212             # print('HTTP CODE: {}'.format(http_code))
213             # print('RESP: {}'.format(resp))
214             # if http_code in (200, 201, 202, 204):
215 0             if resp:
216 0                 resp = json.loads(resp)
217 0             if not resp or "id" not in resp:
218 0                 raise ClientException(
219                     "unexpected response from server - {}".format(resp)
220                 )
221 0             print(resp["id"])
222             # else:
223             #     msg = "Error {}".format(http_code)
224             #     if resp:
225             #         try:
226             #             msg = "{} - {}".format(msg, json.loads(resp))
227             #         except ValueError:
228             #             msg = "{} - {}".format(msg, resp)
229             #     raise ClientException("failed to create/update nst - {}".format(msg))
230
231 1     def update(self, name, filename):
232 0         self._logger.debug("")
233 0         nst = self.get(name)
234 0         endpoint = "{}/{}/nst_content".format(self._apiBase, nst["_id"])
235 0         self.create(filename=filename, update_endpoint=endpoint)