create base package 'osm_ro_plugin' for plugin
[osm/RO.git] / RO-plugin / osm_ro_plugin / vim_dummy.py
1 # -*- coding: utf-8 -*-
2
3 ##
4 # Copyright 2020 Telefonica Investigacion y Desarrollo, S.A.U.
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
16 # under the License.
17 ##
18
19 """
20 Implements a Dummy vim plugin.
21 """
22
23 import yaml
24 from osm_ro_plugin import vimconn
25 from uuid import uuid4
26 from copy import deepcopy
27
28 __author__ = "Alfonso Tierno"
29 __date__ = "2020-04-20"
30
31
32 class VimDummyConnector(vimconn.VimConnector):
33 """Dummy vim connector that does nothing
34 Provide config with:
35 vm_ip: ip address to provide at VM creation. For some tests must be a valid reachable VM
36 ssh_key: private ssh key to use for inserting an authorized ssh key
37 """
38 def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None, log_level=None,
39 config={}, persistent_info={}):
40 super().__init__(uuid, name, tenant_id, tenant_name, url, url_admin, user, passwd, log_level,
41 config, persistent_info)
42 self.nets = {
43 "mgmt": {
44 "id": "mgmt",
45 "name": "mgmt",
46 "status": "ACTIVE",
47 "vim_info": '{status: ACTIVE}'
48 }
49 }
50 self.vms = {}
51 self.flavors = {}
52 self.tenants = {}
53 # preload some images
54 self.images = {
55 "90681b39-dc09-49b7-ba2e-2c00c6b33b76": {
56 "id": "90681b39-dc09-49b7-ba2e-2c00c6b33b76",
57 "name": "cirros034",
58 "checksum": "ee1eca47dc88f4879d8a229cc70a07c6"
59 },
60 "83a39656-65db-47dc-af03-b55289115a53": {
61 "id": "",
62 "name": "cirros040",
63 "checksum": "443b7623e27ecf03dc9e01ee93f67afe"
64 },
65 "208314f2-8eb6-4101-965d-fe2ffbaedf3c": {
66 "id": "208314f2-8eb6-4101-965d-fe2ffbaedf3c",
67 "name": "ubuntu18.04",
68 "checksum": "b6fc7b9b91bca32e989e1edbcdeecb95"
69 },
70 "c03321f8-4b6e-4045-a309-1b3878bd32c1": {
71 "id": "c03321f8-4b6e-4045-a309-1b3878bd32c1",
72 "name": "ubuntu16.04",
73 "checksum": "8f08442faebad2d4a99fedb22fca11b5"
74 },
75 "4f6399a2-3554-457e-916e-ada01f8b950b": {
76 "id": "4f6399a2-3554-457e-916e-ada01f8b950b",
77 "name": "ubuntu1604",
78 "checksum": "8f08442faebad2d4a99fedb22fca11b5"
79 },
80 "59ac0b79-5c7d-4e83-b517-4c6c6a8ac1d3": {
81 "id": "59ac0b79-5c7d-4e83-b517-4c6c6a8ac1d3",
82 "name": "hackfest3-mgmt",
83 "checksum": "acec1e5d5ad7be9be7e6342a16bcf66a"
84 },
85 "f8818a03-f099-4c18-b1c7-26b1324203c1": {
86 "id": "f8818a03-f099-4c18-b1c7-26b1324203c1",
87 "name": "hackfest-pktgen",
88 "checksum": "f8818a03-f099-4c18-b1c7-26b1324203c1"
89 },
90 }
91
92 def new_network(self, net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None):
93 net_id = str(uuid4())
94 net = {
95 "id": net_id,
96 "name": net_name,
97 "net_type": net_type,
98 "status": "ACTIVE",
99 }
100 self.nets[net_id] = net
101 return net_id, net
102
103 def get_network_list(self, filter_dict=None):
104 nets = []
105 for net_id, net in self.nets.items():
106 if filter_dict and filter_dict.get("name"):
107 if net["name"] != filter_dict.get("name"):
108 continue
109 if filter_dict and filter_dict.get("id"):
110 if net_id != filter_dict.get("id"):
111 continue
112 nets.append(net)
113 return nets
114
115 def get_network(self, net_id):
116 if net_id not in self.nets:
117 raise vimconn.VimConnNotFoundException("network with id {} not found".format(net_id))
118 return self.nets[net_id]
119
120 def delete_network(self, net_id, created_items=None):
121 if net_id not in self.nets:
122 raise vimconn.VimConnNotFoundException("network with id {} not found".format(net_id))
123 return net_id
124 self.nets.pop(net_id)
125
126 def refresh_nets_status(self, net_list):
127 nets = {}
128 for net_id in net_list:
129 if net_id not in self.nets:
130 net = {"status": "DELETED"}
131 else:
132 net = self.nets[net_id].copy()
133 net["vim_info"] = yaml.dump({"status": "ACTIVE", "name": net["name"]},
134 default_flow_style=True, width=256)
135 nets[net_id] = net
136
137 return nets
138
139 def get_flavor(self, flavor_id):
140 if flavor_id not in self.flavors:
141 raise vimconn.VimConnNotFoundException("flavor with id {} not found".format(flavor_id))
142 return self.flavors[flavor_id]
143
144 def new_flavor(self, flavor_data):
145 flavor_id = str(uuid4())
146 flavor = deepcopy(flavor_data)
147 flavor["id"] = flavor_id
148 if "name" not in flavor:
149 flavor["name"] = flavor_id
150 self.flavors[flavor_id] = flavor
151 return flavor_id
152
153 def delete_flavor(self, flavor_id):
154 if flavor_id not in self.flavors:
155 raise vimconn.VimConnNotFoundException("flavor with id {} not found".format(flavor_id))
156 return flavor_id
157 self.flavors.pop(flavor_id)
158
159 def get_flavor_id_from_data(self, flavor_dict):
160 for flavor_id, flavor_data in self.flavors.items():
161 for k in ("ram", "vcpus", "disk", "extended"):
162 if flavor_data.get(k) != flavor_dict.get(k):
163 break
164 else:
165 return flavor_id
166 raise vimconn.VimConnNotFoundException("flavor with ram={} cpu={} disk={} {} not found".format(
167 flavor_dict["ram"], flavor_dict["vcpus"], flavor_dict["disk"],
168 "and extended" if flavor_dict.get("extended") else ""))
169
170 def new_tenant(self, tenant_name, tenant_description):
171 tenant_id = str(uuid4())
172 tenant = {'name': tenant_name, 'description': tenant_description, 'id': tenant_id}
173 self.tenants[tenant_id] = tenant
174 return tenant_id
175
176 def delete_tenant(self, tenant_id):
177 if tenant_id not in self.tenants:
178 raise vimconn.VimConnNotFoundException("tenant with id {} not found".format(tenant_id))
179 return tenant_id
180 self.tenants.pop(tenant_id)
181
182 def get_tenant_list(self, filter_dict=None):
183 tenants = []
184 for tenant_id, tenant in self.tenants.items():
185 if filter_dict and filter_dict.get("name"):
186 if tenant["name"] != filter_dict.get("name"):
187 continue
188 if filter_dict and filter_dict.get("id"):
189 if tenant_id != filter_dict.get("id"):
190 continue
191 tenants.append(tenant)
192 return tenants
193
194 def new_image(self, image_dict):
195 image_id = str(uuid4())
196 image = deepcopy(image_dict)
197 image["id"] = image_id
198 if "name" not in image:
199 image["id"] = image_id
200 self.images[image_id] = image
201 return image_id
202
203 def delete_image(self, image_id):
204 if image_id not in self.images:
205 raise vimconn.VimConnNotFoundException("image with id {} not found".format(image_id))
206 return image_id
207 self.images.pop(image_id)
208
209 def get_image_list(self, filter_dict=None):
210 images = []
211 for image_id, image in self.images.items():
212 if filter_dict and filter_dict.get("name"):
213 if image["name"] != filter_dict.get("name"):
214 continue
215 if filter_dict and filter_dict.get("checksum"):
216 if image["checksum"] != filter_dict.get("checksum"):
217 continue
218 if filter_dict and filter_dict.get("id"):
219 if image_id != filter_dict.get("id"):
220 continue
221 images.append(image)
222 return images
223
224 def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None, disk_list=None,
225 availability_zone_index=None, availability_zone_list=None):
226 vm_id = str(uuid4())
227 interfaces = []
228 for iface_index, iface in enumerate(net_list):
229 iface["vim_id"] = str(iface_index)
230 interface = {
231 "ip_address": self.config.get("vm_ip") or "192.168.4.2",
232 "vim_interface_id": str(iface_index),
233 "vim_net_id": iface["net_id"],
234 }
235 interfaces.append(interface)
236 vm = {
237 "id": vm_id,
238 "name": name,
239 "status": "ACTIVE",
240 "description": description,
241 "interfaces": interfaces,
242 "image_id": image_id,
243 "flavor_id": flavor_id,
244 }
245 if image_id not in self.images:
246 self.logger.error("vm create, image_id '{}' not found. Skip".format(image_id))
247 if flavor_id not in self.flavors:
248 self.logger.error("vm create flavor_id '{}' not found. Skip".format(flavor_id))
249 self.vms[vm_id] = vm
250 return vm_id, vm
251
252 def get_vminstance(self, vm_id):
253 if vm_id not in self.vms:
254 raise vimconn.VimConnNotFoundException("vm with id {} not found".format(vm_id))
255 return self.vms[vm_id]
256
257 def delete_vminstance(self, vm_id, created_items=None):
258 if vm_id not in self.vms:
259 raise vimconn.VimConnNotFoundException("vm with id {} not found".format(vm_id))
260 return vm_id
261 self.vms.pop(vm_id)
262
263 def refresh_vms_status(self, vm_list):
264 vms = {}
265 for vm_id in vm_list:
266 if vm_id not in self.vms:
267 vm = {"status": "DELETED"}
268 else:
269 vm = deepcopy(self.vms[vm_id])
270 vm["vim_info"] = yaml.dump({"status": "ACTIVE", "name": vm["name"]},
271 default_flow_style=True, width=256)
272 vms[vm_id] = vm
273 return vms
274
275 def action_vminstance(self, vm_id, action_dict, created_items={}):
276 return None
277
278 def inject_user_key(self, ip_addr=None, user=None, key=None, ro_key=None, password=None):
279 if self.config.get("ssh_key"):
280 ro_key = self.config.get("ssh_key")
281 return super().inject_user_key(ip_addr=ip_addr, user=user, key=key, ro_key=ro_key, password=password)