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