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
import utils
27 #from os.path import basename
31 def __init__(self
, http
=None, client
=None):
34 self
._apiName
= '/vnfpkgm'
35 self
._apiVersion
= '/v1'
36 self
._apiResource
= '/vnf_packages'
37 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
38 self
._apiVersion
, self
._apiResource
)
39 #self._apiBase='/vnfds'
41 def list(self
, filter=None):
44 filter_string
= '?{}'.format(filter)
45 resp
= self
._http
.get_cmd('{}{}'.format(self
._apiBase
,filter_string
))
51 if utils
.validate_uuid4(name
):
52 for vnfd
in self
.list():
53 if name
== vnfd
['_id']:
56 for vnfd
in self
.list():
57 if 'name' in vnfd
and name
== vnfd
['name']:
59 raise NotFound("vnfd {} not found".format(name
))
61 def get_individual(self
, name
):
63 # It is redundant, since the previous one already gets the whole vnfpkginfo
64 # The only difference is that a different primitive is exercised
65 resp
= self
._http
.get_cmd('{}/{}'.format(self
._apiBase
, vnfd
['_id']))
66 #print yaml.safe_dump(resp)
69 raise NotFound("vnfd {} not found".format(name
))
71 def get_thing(self
, name
, thing
, filename
):
73 headers
= self
._client
._headers
74 headers
['Accept'] = 'application/binary'
75 http_code
, resp
= self
._http
.get2_cmd('{}/{}/{}'.format(self
._apiBase
, vnfd
['_id'], thing
))
76 #print 'HTTP CODE: {}'.format(http_code)
77 #print 'RESP: {}'.format(resp)
78 if http_code
in (200, 201, 202, 204):
86 msg
= json
.loads(resp
)
89 raise ClientException("failed to get {} from {} - {}".format(thing
, name
, msg
))
91 def get_descriptor(self
, name
, filename
):
92 self
.get_thing(name
, 'vnfd', filename
)
94 def get_package(self
, name
, filename
):
95 self
.get_thing(name
, 'package_content', filename
)
97 def get_artifact(self
, name
, artifact
, filename
):
98 self
.get_thing(name
, 'artifacts/{}'.format(artifact
), filename
)
100 def delete(self
, name
, force
=False):
101 vnfd
= self
.get(name
)
104 querystring
= '?FORCE=True'
105 http_code
, resp
= self
._http
.delete_cmd('{}/{}{}'.format(self
._apiBase
,
106 vnfd
['_id'], querystring
))
107 #print 'HTTP CODE: {}'.format(http_code)
108 #print 'RESP: {}'.format(resp)
110 print('Deletion in progress')
111 elif http_code
== 204:
117 msg
= json
.loads(resp
)
120 raise ClientException("failed to delete vnfd {} - {}".format(name
, msg
))
122 def create(self
, filename
, overwrite
=None, update_endpoint
=None):
123 mime_type
= magic
.from_file(filename
, mime
=True)
124 if mime_type
is None:
125 raise ClientException(
126 "failed to guess MIME type for file '{}'".format(filename
))
127 headers
= self
._client
._headers
128 if mime_type
in ['application/yaml', 'text/plain']:
129 headers
['Content-Type'] = 'application/yaml'
130 elif mime_type
== 'application/gzip':
131 headers
['Content-Type'] = 'application/gzip'
132 #headers['Content-Type'] = 'application/binary'
133 # Next three lines are to be removed in next version
134 #headers['Content-Filename'] = basename(filename)
135 #file_size = stat(filename).st_size
136 #headers['Content-Range'] = 'bytes 0-{}/{}'.format(file_size - 1, file_size)
138 raise ClientException(
139 "Unexpected MIME type for file {}: MIME type {}".format(
142 headers
["Content-File-MD5"] = utils
.md5(filename
)
143 http_header
= ['{}: {}'.format(key
,val
)
144 for (key
,val
) in list(headers
.items())]
145 self
._http
.set_http_header(http_header
)
147 http_code
, resp
= self
._http
.put_cmd(endpoint
=update_endpoint
, filename
=filename
)
151 ow_string
= '?{}'.format(overwrite
)
152 self
._apiResource
= '/vnf_packages_content'
153 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
154 self
._apiVersion
, self
._apiResource
)
155 endpoint
= '{}{}'.format(self
._apiBase
,ow_string
)
156 http_code
, resp
= self
._http
.post_cmd(endpoint
=endpoint
, filename
=filename
)
157 #print 'HTTP CODE: {}'.format(http_code)
158 #print 'RESP: {}'.format(resp)
159 if http_code
in (200, 201, 202, 204):
161 resp
= json
.loads(resp
)
162 if not resp
or 'id' not in resp
:
163 raise ClientException('unexpected response from server: '.format(
167 msg
= "Error {}".format(http_code
)
170 msg
= "{} - {}".format(msg
, json
.loads(resp
))
172 msg
= "{} - {}".format(msg
, resp
)
173 raise ClientException("failed to create/update vnfd - {}".format(msg
))
175 def update(self
, name
, filename
):
176 vnfd
= self
.get(name
)
177 endpoint
= '{}/{}/vnfd_content'.format(self
._apiBase
, vnfd
['_id'])
178 self
.create(filename
=filename
, update_endpoint
=endpoint
)