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
21 from osmclient
.common
.exceptions
import NotFound
22 from osmclient
.common
.exceptions
import ClientException
23 from osmclient
.common
.exceptions
import OsmHttpException
24 from osmclient
.common
import utils
27 from os
.path
import basename
34 def __init__(self
, http
=None, client
=None):
37 self
._logger
= logging
.getLogger('osmclient')
38 self
._apiName
= '/vnfpkgm'
39 self
._apiVersion
= '/v1'
40 self
._apiResource
= '/vnf_packages'
41 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
42 self
._apiVersion
, self
._apiResource
)
43 #self._apiBase='/vnfds'
45 def list(self
, filter=None):
46 self
._logger
.debug("")
47 self
._client
.get_token()
50 filter_string
= '?{}'.format(filter)
51 _
, resp
= self
._http
.get2_cmd('{}{}'.format(self
._apiBase
,filter_string
))
53 return json
.loads(resp
)
57 self
._logger
.debug("")
58 self
._client
.get_token()
59 if utils
.validate_uuid4(name
):
60 for vnfd
in self
.list():
61 if name
== vnfd
['_id']:
64 for vnfd
in self
.list():
65 if 'name' in vnfd
and name
== vnfd
['name']:
67 raise NotFound("vnfd {} not found".format(name
))
69 def get_individual(self
, name
):
70 self
._logger
.debug("")
72 # It is redundant, since the previous one already gets the whole vnfpkginfo
73 # The only difference is that a different primitive is exercised
74 _
, resp
= self
._http
.get2_cmd('{}/{}'.format(self
._apiBase
, vnfd
['_id']))
75 #print(yaml.safe_dump(resp))
77 return json
.loads(resp
)
78 raise NotFound("vnfd {} not found".format(name
))
80 def get_thing(self
, name
, thing
, filename
):
81 self
._logger
.debug("")
83 headers
= self
._client
._headers
84 headers
['Accept'] = 'application/binary'
85 http_code
, resp
= self
._http
.get2_cmd('{}/{}/{}'.format(self
._apiBase
, vnfd
['_id'], thing
))
86 #print('HTTP CODE: {}'.format(http_code))
87 #print('RESP: {}'.format(resp))
88 #if http_code in (200, 201, 202, 204):
91 return json
.loads(resp
)
96 # msg = json.loads(resp)
99 # raise ClientException("failed to get {} from {} - {}".format(thing, name, msg))
101 def get_descriptor(self
, name
, filename
):
102 self
._logger
.debug("")
103 self
.get_thing(name
, 'vnfd', filename
)
105 def get_package(self
, name
, filename
):
106 self
._logger
.debug("")
107 self
.get_thing(name
, 'package_content', filename
)
109 def get_artifact(self
, name
, artifact
, filename
):
110 self
._logger
.debug("")
111 self
.get_thing(name
, 'artifacts/{}'.format(artifact
), filename
)
113 def delete(self
, name
, force
=False):
114 self
._logger
.debug("")
115 self
._client
.get_token()
116 vnfd
= self
.get(name
)
119 querystring
= '?FORCE=True'
120 http_code
, resp
= self
._http
.delete_cmd('{}/{}{}'.format(self
._apiBase
,
121 vnfd
['_id'], querystring
))
122 #print('HTTP CODE: {}'.format(http_code))
123 #print('RESP: {}'.format(resp))
125 print('Deletion in progress')
126 elif http_code
== 204:
132 msg
= json
.loads(resp
)
135 raise OsmHttpException("failed to delete vnfd {} - {}".format(name
, msg
))
137 def create(self
, filename
, overwrite
=None, update_endpoint
=None):
138 self
._logger
.debug("")
139 self
._client
.get_token()
140 mime_type
= magic
.from_file(filename
, mime
=True)
141 if mime_type
is None:
142 raise ClientException(
143 "failed to guess MIME type for file '{}'".format(filename
))
144 headers
= self
._client
._headers
145 headers
['Content-Filename'] = basename(filename
)
146 if mime_type
in ['application/yaml', 'text/plain', 'application/json']:
147 headers
['Content-Type'] = 'text/plain'
148 elif mime_type
in ['application/gzip', 'application/x-gzip']:
149 headers
['Content-Type'] = 'application/gzip'
150 #headers['Content-Type'] = 'application/binary'
151 # Next three lines are to be removed in next version
152 #headers['Content-Filename'] = basename(filename)
153 #file_size = stat(filename).st_size
154 #headers['Content-Range'] = 'bytes 0-{}/{}'.format(file_size - 1, file_size)
156 raise ClientException(
157 "Unexpected MIME type for file {}: MIME type {}".format(
160 headers
["Content-File-MD5"] = utils
.md5(filename
)
161 http_header
= ['{}: {}'.format(key
,val
)
162 for (key
,val
) in list(headers
.items())]
163 self
._http
.set_http_header(http_header
)
165 http_code
, resp
= self
._http
.put_cmd(endpoint
=update_endpoint
, filename
=filename
)
169 ow_string
= '?{}'.format(overwrite
)
170 self
._apiResource
= '/vnf_packages_content'
171 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
172 self
._apiVersion
, self
._apiResource
)
173 endpoint
= '{}{}'.format(self
._apiBase
,ow_string
)
174 http_code
, resp
= self
._http
.post_cmd(endpoint
=endpoint
, filename
=filename
)
175 #print('HTTP CODE: {}'.format(http_code))
176 #print('RESP: {}'.format(resp))
177 if http_code
in (200, 201, 202):
179 resp
= json
.loads(resp
)
180 if not resp
or 'id' not in resp
:
181 raise OsmHttpException('unexpected response from server: '.format(resp
))
183 elif http_code
== 204:
186 # msg = "Error {}".format(http_code)
189 # msg = "{} - {}".format(msg, json.loads(resp))
191 # msg = "{} - {}".format(msg, resp)
192 # raise ClientException("failed to create/update vnfd - {}".format(msg))
194 def update(self
, name
, filename
):
195 self
._logger
.debug("")
196 self
._client
.get_token()
197 vnfd
= self
.get(name
)
198 endpoint
= '{}/{}/package_content'.format(self
._apiBase
, vnfd
['_id'])
199 self
.create(filename
=filename
, update_endpoint
=endpoint
)