Adding logging capabilities to osmclient
[osm/osmclient.git] / 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 """
18 OSM NST (Network Slice Template) API handling
19 """
20
21 from osmclient.common.exceptions import NotFound
22 from osmclient.common.exceptions import ClientException
23 from osmclient.common import utils
24 import json
25 import magic
26 import logging
27 #from os import stat
28 #from os.path import basename
29
30 class Nst(object):
31
32 def __init__(self, http=None, client=None):
33 self._http = http
34 self._client = client
35 self._logger = logging.getLogger('osmclient')
36 self._apiName = '/nst'
37 self._apiVersion = '/v1'
38 self._apiResource = '/netslice_templates'
39 self._apiBase = '{}{}{}'.format(self._apiName,
40 self._apiVersion, self._apiResource)
41
42 def list(self, filter=None):
43 self._logger.debug("")
44 self._client.get_token()
45 filter_string = ''
46 if filter:
47 filter_string = '?{}'.format(filter)
48 resp = self._http.get_cmd('{}{}'.format(self._apiBase, filter_string))
49 #print(yaml.safe_dump(resp))
50 if resp:
51 return resp
52 return list()
53
54 def get(self, name):
55 self._logger.debug("")
56 self._client.get_token()
57 if utils.validate_uuid4(name):
58 for nst in self.list():
59 if name == nst['_id']:
60 return nst
61 else:
62 for nst in self.list():
63 if 'name' in nst and name == nst['name']:
64 return nst
65 raise NotFound("nst {} not found".format(name))
66
67 def get_individual(self, name):
68 self._logger.debug("")
69 nst = self.get(name)
70 # It is redundant, since the previous one already gets the whole nstinfo
71 # The only difference is that a different primitive is exercised
72 resp = self._http.get_cmd('{}/{}'.format(self._apiBase, nst['_id']))
73 #print(yaml.safe_dump(resp))
74 if resp:
75 return resp
76 raise NotFound("nst {} not found".format(name))
77
78 def get_thing(self, name, thing, filename):
79 self._logger.debug("")
80 nst = self.get(name)
81 headers = self._client._headers
82 headers['Accept'] = 'application/binary'
83 http_code, resp = self._http.get2_cmd('{}/{}/{}'.format(self._apiBase, nst['_id'], thing))
84 #print('HTTP CODE: {}'.format(http_code))
85 #print('RESP: {}'.format(resp))
86 if http_code in (200, 201, 202, 204):
87 if resp:
88 #store in a file
89 return resp
90 else:
91 msg = ""
92 if resp:
93 try:
94 msg = json.loads(resp)
95 except ValueError:
96 msg = resp
97 raise ClientException("failed to get {} from {} - {}".format(thing, name, msg))
98
99 def get_descriptor(self, name, filename):
100 self._logger.debug("")
101 self.get_thing(name, 'nst', filename)
102
103 def get_package(self, name, filename):
104 self._logger.debug("")
105 self.get_thing(name, 'nst_content', filename)
106
107 def get_artifact(self, name, artifact, filename):
108 self._logger.debug("")
109 self.get_thing(name, 'artifacts/{}'.format(artifact), filename)
110
111 def delete(self, name, force=False):
112 self._logger.debug("")
113 nst = self.get(name)
114 querystring = ''
115 if force:
116 querystring = '?FORCE=True'
117 http_code, resp = self._http.delete_cmd('{}/{}{}'.format(self._apiBase,
118 nst['_id'], querystring))
119 #print('HTTP CODE: {}'.format(http_code))
120 #print('RESP: {}'.format(resp))
121 if http_code == 202:
122 print('Deletion in progress')
123 elif http_code == 204:
124 print('Deleted')
125 else:
126 msg = ""
127 if resp:
128 try:
129 resp = json.loads(resp)
130 except ValueError:
131 msg = resp
132 raise ClientException("failed to delete nst {} - {}".format(name, msg))
133
134 def create(self, filename, overwrite=None, update_endpoint=None):
135 self._logger.debug("")
136 self._client.get_token()
137 mime_type = magic.from_file(filename, mime=True)
138 if mime_type is None:
139 raise ClientException(
140 "failed to guess MIME type for file '{}'".format(filename))
141 headers= self._client._headers
142 if mime_type in ['application/yaml', 'text/plain']:
143 headers['Content-Type'] = 'application/yaml'
144 elif mime_type in ['application/gzip', 'application/x-gzip']:
145 headers['Content-Type'] = 'application/gzip'
146 #headers['Content-Type'] = 'application/binary'
147 # Next three lines are to be removed in next version
148 #headers['Content-Filename'] = basename(filename)
149 #file_size = stat(filename).st_size
150 #headers['Content-Range'] = 'bytes 0-{}/{}'.format(file_size - 1, file_size)
151 else:
152 raise ClientException(
153 "Unexpected MIME type for file {}: MIME type {}".format(
154 filename, mime_type)
155 )
156 headers["Content-File-MD5"] = utils.md5(filename)
157 http_header = ['{}: {}'.format(key,val)
158 for (key,val) in list(headers.items())]
159 self._http.set_http_header(http_header)
160 if update_endpoint:
161 http_code, resp = self._http.put_cmd(endpoint=update_endpoint, filename=filename)
162 else:
163 ow_string = ''
164 if overwrite:
165 ow_string = '?{}'.format(overwrite)
166 self._apiResource = '/netslice_templates_content'
167 self._apiBase = '{}{}{}'.format(self._apiName,
168 self._apiVersion, self._apiResource)
169 endpoint = '{}{}'.format(self._apiBase,ow_string)
170 http_code, resp = self._http.post_cmd(endpoint=endpoint, filename=filename)
171 #print('HTTP CODE: {}'.format(http_code))
172 #print('RESP: {}'.format(resp))
173 if http_code in (200, 201, 202, 204):
174 if resp:
175 resp = json.loads(resp)
176 if not resp or 'id' not in resp:
177 raise ClientException('unexpected response from server - {}'.format(
178 resp))
179 print(resp['id'])
180 else:
181 msg = "Error {}".format(http_code)
182 if resp:
183 try:
184 msg = "{} - {}".format(msg, json.loads(resp))
185 except ValueError:
186 msg = "{} - {}".format(msg, resp)
187 raise ClientException("failed to create/update nst - {}".format(msg))
188
189 def update(self, name, filename):
190 self._logger.debug("")
191 nst = self.get(name)
192 endpoint = '{}/{}/nst_content'.format(self._apiBase, nst['_id'])
193 self.create(filename=filename, update_endpoint=endpoint)
194