update Makefile, pep8, scaling
[osm/osmclient.git] / osmclient / v1 / ns.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 ns API handling
19 """
20
21 from osmclient.common import utils
22 from osmclient.common.exceptions import ClientException
23 from osmclient.common.exceptions import NotFound
24 import uuid
25
26
27 class Ns(object):
28
29 def __init__(self, http=None, client=None):
30 self._http = http
31 self._client = client
32
33 def list(self):
34 """Returns a list of ns's
35 """
36 resp = self._http.get_cmd('api/running/ns-instance-config')
37
38 if not resp or 'nsr:ns-instance-config' not in resp:
39 return list()
40
41 if 'nsr' not in resp['nsr:ns-instance-config']:
42 return list()
43
44 return resp['nsr:ns-instance-config']['nsr']
45
46 def get(self, name):
47 """Returns an ns based on name
48 """
49 for ns in self.list():
50 if name == ns['name']:
51 return ns
52 raise NotFound("ns {} not found".format(name))
53
54 def scale(self, ns_name, ns_scale_group, instance_index):
55 postdata = {}
56 postdata['instance'] = list()
57 instance = {}
58 instance['id'] = instance_index
59 postdata['instance'].append(instance)
60
61 ns = self.get(ns_name)
62 resp = self._http.post_cmd(
63 'v1/api/config/ns-instance-config/nsr/{}/scaling-group/{}/instance'
64 .format(ns['id'], ns_scale_group), postdata)
65 if 'success' not in resp:
66 raise ClientException(
67 "failed to scale ns: {} result: {}".format(
68 ns_name,
69 resp))
70
71 def create(self, nsd_name, nsr_name, account, vim_network_prefix=None,
72 ssh_keys=None, description='default description',
73 admin_status='ENABLED'):
74 postdata = {}
75 postdata['nsr'] = list()
76 nsr = {}
77 nsr['id'] = str(uuid.uuid1())
78
79 nsd = self._client.nsd.get(nsd_name)
80
81 datacenter = self._client.vim.get_datacenter(account)
82 if datacenter is None:
83 raise NotFound("cannot find datacenter account {}".format(account))
84
85 nsr['nsd'] = nsd
86 nsr['name'] = nsr_name
87 nsr['short-name'] = nsr_name
88 nsr['description'] = description
89 nsr['admin-status'] = admin_status
90 nsr['om-datacenter'] = datacenter['uuid']
91
92 if ssh_keys is not None:
93 # ssh_keys is comma separate list
94 ssh_keys_format = []
95 for key in ssh_keys.split(','):
96 ssh_keys_format.append({'key-pair-ref': key})
97
98 nsr['ssh-authorized-key'] = ssh_keys_format
99
100 if vim_network_prefix is not None:
101 for index, vld in enumerate(nsr['nsd']['vld']):
102 network_name = vld['name']
103 nsr['nsd']['vld'][index]['vim-network-name'] = '{}-{}'.format(
104 vim_network_prefix, network_name)
105
106 postdata['nsr'].append(nsr)
107
108 resp = self._http.post_cmd(
109 'api/config/ns-instance-config/nsr',
110 postdata)
111
112 if 'success' not in resp:
113 raise ClientException(
114 "failed to create ns: {} nsd: {} result: {}".format(
115 nsr_name,
116 nsd_name,
117 resp))
118
119 def get_opdata(self, id):
120 return self._http.get_cmd(
121 'api/operational/ns-instance-opdata/nsr/{}?deep'.format(id))
122
123 def get_field(self, ns_name, field):
124 nsr = self.get(ns_name)
125 if nsr is None:
126 raise NotFound("failed to retrieve ns {}".format(ns_name))
127
128 if field in nsr:
129 return nsr[field]
130
131 nsopdata = self.get_opdata(nsr['id'])
132
133 if field in nsopdata['nsr:nsr']:
134 return nsopdata['nsr:nsr'][field]
135
136 raise NotFound("failed to find {} in ns {}".format(field, ns_name))
137
138 def _terminate(self, ns_name):
139 ns = self.get(ns_name)
140 if ns is None:
141 raise NotFound("cannot find ns {}".format(ns_name))
142
143 return self._http.delete_cmd('api/config/ns-instance-config/nsr/' +
144 ns['id'])
145
146 def delete(self, ns_name, wait=True):
147 vnfs = self.get_field(ns_name, 'constituent-vnfr-ref')
148
149 resp = self._terminate(ns_name)
150 if 'success' not in resp:
151 raise ClientException("failed to delete ns {}".format(ns_name))
152
153 # helper method to check if pkg exists
154 def check_not_exists(func):
155 try:
156 func()
157 return False
158 except NotFound:
159 return True
160
161 for vnf in vnfs:
162 if (not utils.wait_for_value(
163 lambda:
164 check_not_exists(lambda:
165 self._client.vnf.get(vnf['vnfr-id'])))):
166 raise ClientException(
167 "vnf {} failed to delete".format(vnf['vnfr-id']))
168 if not utils.wait_for_value(lambda:
169 check_not_exists(lambda:
170 self.get(ns_name))):
171 raise ClientException("ns {} failed to delete".format(ns_name))
172
173 def get_monitoring(self, ns_name):
174 ns = self.get(ns_name)
175 mon_list = {}
176 if ns is None:
177 return mon_list
178
179 vnfs = self._client.vnf.list()
180 for vnf in vnfs:
181 if ns['id'] == vnf['nsr-id-ref']:
182 if 'monitoring-param' in vnf:
183 mon_list[vnf['name']] = vnf['monitoring-param']
184
185 return mon_list