8ea18545b1f61b10f2c8b546009eaa7eba8d9484
[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 if config:
117 ns_config = yaml.load(config)
118
119 if ns_config and 'vim-network-name' in ns_config:
120 for network in ns_config['vim-network-name']:
121 # now find this network
122 vld_name = network['name']
123 vim_vld_name = network['vim-network-name']
124
125 for index, vld in enumerate(nsr['nsd']['vld']):
126 if vld['name'] == vld_name:
127 nsr['nsd']['vld'][index]['vim-network-name'] = network['vim-network-name']
128
129 postdata['nsr'].append(nsr)
130
131 resp = self._http.post_cmd(
132 'api/config/{}ns-instance-config/nsr'
133 .format(self._client.so_rbac_project_path),
134 postdata)
135
136 if 'success' not in resp:
137 raise ClientException(
138 "failed to create ns: {} nsd: {} result: {}".format(
139 nsr_name,
140 nsd_name,
141 resp))
142
143 def get_opdata(self, id):
144 return self._http.get_cmd(
145 'api/operational/{}ns-instance-opdata/nsr/{}?deep'
146 .format(self._client.so_rbac_project_path, id))
147
148 def get_field(self, ns_name, field):
149 nsr = self.get(ns_name)
150 if nsr is None:
151 raise NotFound("failed to retrieve ns {}".format(ns_name))
152
153 if field in nsr:
154 return nsr[field]
155
156 nsopdata = self.get_opdata(nsr['id'])
157
158 if field in nsopdata['nsr:nsr']:
159 return nsopdata['nsr:nsr'][field]
160
161 raise NotFound("failed to find {} in ns {}".format(field, ns_name))
162
163 def _terminate(self, ns_name):
164 ns = self.get(ns_name)
165 if ns is None:
166 raise NotFound("cannot find ns {}".format(ns_name))
167
168 return self._http.delete_cmd('api/config/{}ns-instance-config/nsr/{}'
169 .format(self._client.so_rbac_project_path, ns['id']))
170
171 def delete(self, ns_name, wait=True):
172 vnfs = self.get_field(ns_name, 'constituent-vnfr-ref')
173
174 resp = self._terminate(ns_name)
175 if 'success' not in resp:
176 raise ClientException("failed to delete ns {}".format(ns_name))
177
178 # helper method to check if pkg exists
179 def check_not_exists(func):
180 try:
181 func()
182 return False
183 except NotFound:
184 return True
185
186 for vnf in vnfs:
187 if (not utils.wait_for_value(
188 lambda:
189 check_not_exists(lambda:
190 self._client.vnf.get(vnf['vnfr-id'])))):
191 raise ClientException(
192 "vnf {} failed to delete".format(vnf['vnfr-id']))
193 if not utils.wait_for_value(lambda:
194 check_not_exists(lambda:
195 self.get(ns_name))):
196 raise ClientException("ns {} failed to delete".format(ns_name))
197
198 def get_monitoring(self, ns_name):
199 ns = self.get(ns_name)
200 mon_list = {}
201 if ns is None:
202 return mon_list
203
204 vnfs = self._client.vnf.list()
205 for vnf in vnfs:
206 if ns['id'] == vnf['nsr-id-ref']:
207 if 'monitoring-param' in vnf:
208 mon_list[vnf['name']] = vnf['monitoring-param']
209
210 return mon_list