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