retrieve key/val method from pkg
[osm/osmclient.git] / osmclient / v1 / package.py
1 # Copyright 2017 Sandvine
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 package API handling
19 """
20
21 import tarfile
22 import re
23 import yaml
24 from osmclient.common.exceptions import ClientException
25 from osmclient.common.exceptions import NotFound
26 from osmclient.common import utils
27
28
29 class Package(object):
30 def __init__(self, http=None, upload_http=None, client=None):
31 self._client = client
32 self._http = http
33 self._upload_http = upload_http
34
35 def _wait_for_package(self, pkg_type):
36 if 'vnfd' in pkg_type['type']:
37 get_method = self._client.vnfd.get
38 elif 'nsd' in pkg_type['type']:
39 get_method = self._client.nsd.get
40 else:
41 raise ClientException("no valid package type found")
42
43 # helper method to check if pkg exists
44 def check_exists(func):
45 try:
46 func()
47 except NotFound:
48 return False
49 return True
50
51 return utils.wait_for_value(lambda:
52 check_exists(lambda:
53 get_method(pkg_type['name'])))
54
55 # method opens up a package and finds the name of the resulting
56 # descriptor (vnfd or nsd name)
57 def get_key_val_from_pkg(self, descriptor_file):
58 tar = tarfile.open(descriptor_file)
59 yamlfile = None
60 for member in tar.getmembers():
61 if (re.match('.*.yaml', member.name) and
62 len(member.name.split('/')) == 2):
63 yamlfile = member.name
64 break
65 if yamlfile is None:
66 return None
67
68 dict = yaml.load(tar.extractfile(yamlfile))
69 result = {}
70 for k1, v1 in dict.items():
71 if not k1.endswith('-catalog'):
72 continue
73 for k2, v2 in v1.items():
74 if not k2.endswith('nsd') and not k2.endswith('vnfd'):
75 continue
76
77 if 'nsd' in k2:
78 result['type'] = 'nsd'
79 else:
80 result['type'] = 'vnfd'
81
82 for entry in v2:
83 for k3, v3 in entry.items():
84 # strip off preceeding chars before :
85 key_name = k3.split(':').pop()
86
87 result[key_name] = v3
88 tar.close()
89 return result
90
91 def wait_for_upload(self, filename):
92 """wait(block) for an upload to succeed.
93 The filename passed is assumed to be a descriptor tarball.
94 """
95 pkg_type = self.get_key_val_from_pkg(filename)
96
97 if pkg_type is None:
98 raise ClientException("Cannot determine package type")
99
100 if not self._wait_for_package(pkg_type):
101 raise ClientException("package {} failed to upload"
102 .format(filename))
103
104 def upload(self, filename):
105 resp = self._upload_http.post_cmd(formfile=('package', filename))
106 if not resp or 'transaction_id' not in resp:
107 raise ClientException("failed to upload package")