e75c8f51c19da3890ce218d4e5b3e90a0e25ca86
1 # Copyright 2018 Telefonica
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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
18 OSM NST (Network Slice Template) API handling
21 from osmclient
.common
.exceptions
import NotFound
22 from osmclient
.common
.exceptions
import ClientException
23 from osmclient
.common
import utils
28 #from os.path import basename
32 def __init__(self
, http
=None, client
=None):
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
)
42 def list(self
, filter=None):
43 self
._logger
.debug("")
44 self
._client
.get_token()
47 filter_string
= '?{}'.format(filter)
48 resp
= self
._http
.get_cmd('{}{}'.format(self
._apiBase
, filter_string
))
49 #print(yaml.safe_dump(resp))
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']:
62 for nst
in self
.list():
63 if 'name' in nst
and name
== nst
['name']:
65 raise NotFound("nst {} not found".format(name
))
67 def get_individual(self
, name
):
68 self
._logger
.debug("")
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))
76 raise NotFound("nst {} not found".format(name
))
78 def get_thing(self
, name
, thing
, filename
):
79 self
._logger
.debug("")
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):
94 msg
= json
.loads(resp
)
97 raise ClientException("failed to get {} from {} - {}".format(thing
, name
, msg
))
99 def get_descriptor(self
, name
, filename
):
100 self
._logger
.debug("")
101 self
.get_thing(name
, 'nst', filename
)
103 def get_package(self
, name
, filename
):
104 self
._logger
.debug("")
105 self
.get_thing(name
, 'nst_content', filename
)
107 def get_artifact(self
, name
, artifact
, filename
):
108 self
._logger
.debug("")
109 self
.get_thing(name
, 'artifacts/{}'.format(artifact
), filename
)
111 def delete(self
, name
, force
=False):
112 self
._logger
.debug("")
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))
122 print('Deletion in progress')
123 elif http_code
== 204:
129 resp
= json
.loads(resp
)
132 raise ClientException("failed to delete nst {} - {}".format(name
, msg
))
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)
152 raise ClientException(
153 "Unexpected MIME type for file {}: MIME type {}".format(
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
)
161 http_code
, resp
= self
._http
.put_cmd(endpoint
=update_endpoint
, filename
=filename
)
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):
175 resp
= json
.loads(resp
)
176 if not resp
or 'id' not in resp
:
177 raise ClientException('unexpected response from server - {}'.format(
181 msg
= "Error {}".format(http_code
)
184 msg
= "{} - {}".format(msg
, json
.loads(resp
))
186 msg
= "{} - {}".format(msg
, resp
)
187 raise ClientException("failed to create/update nst - {}".format(msg
))
189 def update(self
, name
, filename
):
190 self
._logger
.debug("")
192 endpoint
= '{}/{}/nst_content'.format(self
._apiBase
, nst
['_id'])
193 self
.create(filename
=filename
, update_endpoint
=endpoint
)