fe62e3d437f3b19ca2596864ac9c9b0e078aeca9
[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 .format(self._client.so_rbac_project_path))
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(self._client.so_rbac_project_path, 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 if self._client._so_version == 'v3':
82 datacenter, resource_orchestrator = self._client.vim.get_datacenter(account)
83 if datacenter is None or resource_orchestrator is None:
84 raise NotFound("cannot find datacenter account {}".format(account))
85 if 'uuid' not in datacenter:
86 raise NotFound("The RO Datacenter - {} is invalid. Please select another".format(account))
87 else:
88 # Backwards Compatiility
89 datacenter = self._client.vim.get_datacenter(account)
90 if datacenter is None:
91 raise NotFound("cannot find datacenter account {}".format(account))
92
93 nsr['nsd'] = nsd
94 nsr['name'] = nsr_name
95 nsr['short-name'] = nsr_name
96 nsr['description'] = description
97 nsr['admin-status'] = admin_status
98
99 if self._client._so_version == 'v3':
100 # New format for V3
101 nsr['resource-orchestrator'] = resource_orchestrator
102 nsr['datacenter'] = datacenter['name']
103 else:
104 # Backwards Compatiility
105 nsr['om-datacenter'] = datacenter['uuid']
106
107 if ssh_keys is not None:
108 # ssh_keys is comma separate list
109 ssh_keys_format = []
110 for key in ssh_keys.split(','):
111 ssh_keys_format.append({'key-pair-ref': key})
112
113 nsr['ssh-authorized-key'] = ssh_keys_format
114
115 if vim_network_prefix is not None:
116 for index, vld in enumerate(nsr['nsd']['vld']):
117 network_name = vld['name']
118 nsr['nsd']['vld'][index]['vim-network-name'] = '{}-{}'.format(
119 vim_network_prefix, network_name)
120
121 postdata['nsr'].append(nsr)
122
123 resp = self._http.post_cmd(
124 'api/config/{}ns-instance-config/nsr'
125 .format(self._client.so_rbac_project_path),
126 postdata)
127
128 if 'success' not in resp:
129 raise ClientException(
130 "failed to create ns: {} nsd: {} result: {}".format(
131 nsr_name,
132 nsd_name,
133 resp))
134
135 def get_opdata(self, id):
136 return self._http.get_cmd(
137 'api/operational/{}ns-instance-opdata/nsr/{}?deep'
138 .format(self._client.so_rbac_project_path, id))
139
140 def get_field(self, ns_name, field):
141 nsr = self.get(ns_name)
142 if nsr is None:
143 raise NotFound("failed to retrieve ns {}".format(ns_name))
144
145 if field in nsr:
146 return nsr[field]
147
148 nsopdata = self.get_opdata(nsr['id'])
149
150 if field in nsopdata['nsr:nsr']:
151 return nsopdata['nsr:nsr'][field]
152
153 raise NotFound("failed to find {} in ns {}".format(field, ns_name))
154
155 def _terminate(self, ns_name):
156 ns = self.get(ns_name)
157 if ns is None:
158 raise NotFound("cannot find ns {}".format(ns_name))
159
160 return self._http.delete_cmd('api/config/{}ns-instance-config/nsr/{}'
161 .format(self._client.so_rbac_project_path, ns['id']))
162
163 def delete(self, ns_name, wait=True):
164 vnfs = self.get_field(ns_name, 'constituent-vnfr-ref')
165
166 resp = self._terminate(ns_name)
167 if 'success' not in resp:
168 raise ClientException("failed to delete ns {}".format(ns_name))
169
170 # helper method to check if pkg exists
171 def check_not_exists(func):
172 try:
173 func()
174 return False
175 except NotFound:
176 return True
177
178 for vnf in vnfs:
179 if (not utils.wait_for_value(
180 lambda:
181 check_not_exists(lambda:
182 self._client.vnf.get(vnf['vnfr-id'])))):
183 raise ClientException(
184 "vnf {} failed to delete".format(vnf['vnfr-id']))
185 if not utils.wait_for_value(lambda:
186 check_not_exists(lambda:
187 self.get(ns_name))):
188 raise ClientException("ns {} failed to delete".format(ns_name))
189
190 def get_monitoring(self, ns_name):
191 ns = self.get(ns_name)
192 mon_list = {}
193 if ns is None:
194 return mon_list
195
196 vnfs = self._client.vnf.list()
197 for vnf in vnfs:
198 if ns['id'] == vnf['nsr-id-ref']:
199 if 'monitoring-param' in vnf:
200 mon_list[vnf['name']] = vnf['monitoring-param']
201
202 return mon_list