blob: 640176fcbb4622410657e1a1995c05a0a6af4441 [file] [log] [blame]
Tony Mack01942f52013-03-26 14:26:40 -04001from plstackapi.planetstack.config import Config
Tony Mackad8b0932013-04-07 19:32:07 -04002from plstackapi.openstack.client import OpenStackClient
Tony Mack01942f52013-03-26 14:26:40 -04003
Tony Macka033ced2013-03-29 17:57:06 -04004class OpenStackDriver:
Tony Mack01942f52013-03-26 14:26:40 -04005
Tony Mackad8b0932013-04-07 19:32:07 -04006 def __init__(self, config = None, client=None):
Tony Mack01942f52013-03-26 14:26:40 -04007 if config:
8 self.config = Config(config)
9 else:
10 self.config = Config()
Tony Mackad8b0932013-04-07 19:32:07 -040011
Tony Mack0dc2f562013-04-29 19:41:39 -040012 self.admin_client = OpenStackClient()
13 self.admin_user = self.admin_client.keystone.users.find(name=self.admin_client.keystone.username)
14
Tony Mackad8b0932013-04-07 19:32:07 -040015 if client:
16 self.shell = client
17 else:
18 self.shell = OpenStackClient()
Tony Mack01942f52013-03-26 14:26:40 -040019
Tony Mackb5f339f2013-04-08 16:29:38 -040020 def create_role(self, name):
21 roles = self.shell.keystone.roles.findall(name=name)
22 if not roles:
23 role = self.shell.keystone.roles.create(name)
24 else:
25 role = roles[0]
26 return role
27
Tony Macka7040532013-04-08 21:45:43 -040028 def delete_role(self, filter):
29 roles = self.shell.keystone.roles.findall(**filter)
Tony Mackb5f339f2013-04-08 16:29:38 -040030 for role in roles:
31 self.shell.keystone.roles.delete(role)
32 return 1
33
Tony Mack1fbdeca2013-04-06 00:10:36 -040034 def create_tenant(self, tenant_name, enabled, description):
Tony Mack5ee21902013-03-29 20:36:42 -040035 """Create keystone tenant. Suggested fields: name, description, enabled"""
Tony Mack1fbdeca2013-04-06 00:10:36 -040036 tenants = self.shell.keystone.tenants.findall(name=tenant_name)
Tony Mack7823b892013-03-29 20:35:26 -040037 if not tenants:
Tony Mack1fbdeca2013-04-06 00:10:36 -040038 fields = {'tenant_name': tenant_name, 'enabled': enabled,
Tony Mack488950a2013-04-07 20:35:50 -040039 'description': description}
Tony Mack1fbdeca2013-04-06 00:10:36 -040040 tenant = self.shell.keystone.tenants.create(**fields)
Tony Mack7823b892013-03-29 20:35:26 -040041 else:
42 tenant = tenants[0]
Tony Mack0dc2f562013-04-29 19:41:39 -040043
44 # always give the admin user the admin role to any tenant created
45 # by the driver.
46 self.add_user_role(self.admin_user.id, tenant.id, 'admin')
Tony Mack7823b892013-03-29 20:35:26 -040047 return tenant
48
49 def update_tenant(self, id, **kwds):
Tony Mack1fbdeca2013-04-06 00:10:36 -040050 return self.shell.keystone.tenants.update(id, **kwds)
Tony Mack7823b892013-03-29 20:35:26 -040051
52 def delete_tenant(self, id):
Tony Mackfd24d0d2013-04-14 00:59:17 -040053 tenants = self.shell.keystone.tenants.findall(id=id)
54 for tenant in tenants:
55 self.shell.keystone.tenants.delete(tenant)
56 return 1
Tony Mack0211f1b2013-04-04 23:56:24 -040057
Tony Mack1fbdeca2013-04-06 00:10:36 -040058 def create_user(self, name, email, password, enabled):
59 users = self.shell.keystone.users.findall(email=email)
60 if not users:
61 fields = {'name': name, 'email': email, 'password': password,
62 'enabled': enabled}
Tony Mackfdcbf832013-04-09 11:47:11 -040063 user = self.shell.keystone.users.create(**fields)
Tony Mack1fbdeca2013-04-06 00:10:36 -040064 else:
65 user = users[0]
66 return user
67
Tony Mackfd24d0d2013-04-14 00:59:17 -040068 def delete_user(self, id):
69 users = self.shell.keystone.users.findall(id=id)
70 for user in users:
71 self.shell.keystone.users.delete(user)
72 return 1
73
Tony Mack1fbdeca2013-04-06 00:10:36 -040074 def add_user_role(self, user_id, tenant_id, role_name):
75 user = self.shell.keystone.users.find(id=user_id)
76 tenant = self.shell.keystone.tenants.find(id=tenant_id)
Tony Mack54304c62013-04-28 11:27:07 -040077 role = self.shell.keystone.roles.find(name=role_name)
78
79 role_found = False
80 user_roles = user.list_roles(tenant.id)
81 for user_role in user_roles:
82 if user_role.name == role.name:
83 role_found = True
84 if not role_found:
85 tenant.add_user(user, role)
86
87 return 1
Tony Mack1fbdeca2013-04-06 00:10:36 -040088
89 def delete_user_role(self, user_id, tenant_id, role_name):
90 user = self.shell.keystone.users.find(id=user_id)
91 tenant = self.shell.keystone.tenants.find(id=tenant_id)
Tony Mack54304c62013-04-28 11:27:07 -040092 role = self.shell.keystone.roles.find(name=role_name)
93
94 role_found = False
95 user_roles = user.list_roles(tenant.id)
96 for user_role in user_roles:
97 if user_role.name == role.name:
98 role_found = True
99 if role_found:
100 tenant.remove_user(user, role)
101
102 return 1
Tony Mack1fbdeca2013-04-06 00:10:36 -0400103
104 def update_user(self, id, **kwds):
105 return self.shell.keystone.users.update(id, **kwds)
106
Tony Mack240903f2013-04-06 01:31:37 -0400107 def create_router(self, name, set_gateway=True):
Tony Mack28be7562013-04-10 08:45:55 -0400108 routers = self.shell.quantum.list_routers(name=name)['routers']
109 if routers:
110 router = routers[0]
111 else:
Tony Mack62bc59a2013-04-14 23:27:12 -0400112 router = self.shell.quantum.create_router({'router': {'name': name}})['router']
Tony Mackc1665b12013-04-29 16:45:14 -0400113 # add router to external network
Tony Mack240903f2013-04-06 01:31:37 -0400114 if set_gateway:
Tony Mack257bedc2013-04-10 08:58:09 -0400115 nets = self.shell.quantum.list_networks()['networks']
Tony Mack240903f2013-04-06 01:31:37 -0400116 for net in nets:
117 if net['router:external'] == True:
Tony Mack9dcc0502013-04-10 09:07:45 -0400118 self.shell.quantum.add_gateway_router(router['id'],
119 {'network_id': net['id']})
Tony Mack240903f2013-04-06 01:31:37 -0400120
Tony Mack0211f1b2013-04-04 23:56:24 -0400121 return router
122
Tony Mack62bc59a2013-04-14 23:27:12 -0400123 def delete_router(self, id):
124 routers = self.shell.quantum.list_routers(id=id)['routers']
Tony Mack28be7562013-04-10 08:45:55 -0400125 for router in routers:
126 self.shell.quantum.delete_router(router['id'])
Tony Mackc1665b12013-04-29 16:45:14 -0400127 # remove router form external network
Tony Mack0c0e05d2013-04-29 17:52:37 -0400128 #nets = self.shell.quantum.list_networks()['networks']
129 #for net in nets:
130 # if net['router:external'] == True:
131 # self.shell.quantum.remove_gateway_router(router['id'])
Tony Mack240903f2013-04-06 01:31:37 -0400132
133 def add_router_interface(self, router_id, subnet_id):
Tony Mack48952032013-04-12 11:49:34 -0400134 router = self.shell.quantum.show_router(router_id)['router']
135 subnet = self.shell.quantum.show_subnet(subnet_id)['subnet']
Tony Mack240903f2013-04-06 01:31:37 -0400136 if router and subnet:
Tony Mack48952032013-04-12 11:49:34 -0400137 self.shell.quantum.add_interface_router(router_id, {'subnet_id': subnet_id})
Tony Mack240903f2013-04-06 01:31:37 -0400138
139 def delete_router_interface(self, router_id, subnet_id):
Tony Mack48952032013-04-12 11:49:34 -0400140 router = self.shell.quantum.show_router(router_id)
141 subnet = self.shell.quantum.show_subnet(subnet_id)
Tony Mack240903f2013-04-06 01:31:37 -0400142 if router and subnet:
Tony Mack48952032013-04-12 11:49:34 -0400143 self.shell.quantum.remove_interface_router(router_id, {'subnet_id': subnet_id})
Tony Mack240903f2013-04-06 01:31:37 -0400144
Tony Mack0211f1b2013-04-04 23:56:24 -0400145 def create_network(self, name):
Tony Mack28be7562013-04-10 08:45:55 -0400146 nets = self.shell.quantum.list_networks(name=name)['networks']
147 if nets:
Tony Mack53c63342013-04-10 08:11:45 -0400148 net = nets[0]
Tony Mack82a688d2013-04-10 08:12:58 -0400149 else:
Tony Mack62bc59a2013-04-14 23:27:12 -0400150 net = self.shell.quantum.create_network({'network': {'name': name}})['network']
Tony Mack53c63342013-04-10 08:11:45 -0400151 return net
152
Tony Mack62bc59a2013-04-14 23:27:12 -0400153 def delete_network(self, id):
154 nets = self.shell.quantum.list_networks()['networks']
Tony Mack0211f1b2013-04-04 23:56:24 -0400155 for net in nets:
Tony Mack62bc59a2013-04-14 23:27:12 -0400156 if net['id'] == id:
Tony Mack94c6ea02013-04-16 21:41:50 -0400157 # delete_all ports
158 self.delete_network_ports(net['id'])
Tony Mack62bc59a2013-04-14 23:27:12 -0400159 # delete all subnets:
160 for subnet_id in net['subnets']:
161 self.delete_subnet(subnet_id)
162 self.shell.quantum.delete_network(net['id'])
Tony Mackfd24d0d2013-04-14 00:59:17 -0400163 return 1
Tony Mack94c6ea02013-04-16 21:41:50 -0400164
165 def delete_network_ports(self, network_id):
166 ports = self.shell.quantum.list_ports()['ports']
167 for port in ports:
Tony Mackc1665b12013-04-29 16:45:14 -0400168 if port['network_id'] == network_id:
Tony Mack94c6ea02013-04-16 21:41:50 -0400169 self.shell.quantum.delete_port(port['id'])
170 return 1
171
172 def delete_subnet_ports(self, subnet_id):
173 ports = self.shell.quantum.list_ports()['ports']
174 for port in ports:
175 delete = False
176 for fixed_ip in port['fixed_ips']:
177 if fixed_ip['subnet_id'] == subnet_id:
178 delete=True
179 break
180 if delete:
181 self.shell.quantum.delete_port(port['id'])
182 return 1
183
Tony Mack48952032013-04-12 11:49:34 -0400184 def create_subnet(self, name, network_id, cidr_ip, ip_version, start, end):
185 #nets = self.shell.quantum.list_networks(name=network_name)['networks']
186 #if not nets:
187 # raise Exception, "No such network: %s" % network_name
188 #net = nets[0]
Tony Mack0211f1b2013-04-04 23:56:24 -0400189
Tony Mack48952032013-04-12 11:49:34 -0400190 subnet = None
191 subnets = self.shell.quantum.list_subnets()['subnets']
192 for snet in subnets:
193 if snet['cidr'] == cidr_ip and snet['network_id'] == network_id:
194 subnet = snet
195
196 if not subnet:
197 allocation_pools = [{'start': start, 'end': end}]
198 subnet = {'subnet': {'name': name,
199 'network_id': network_id,
200 'ip_version': ip_version,
201 'cidr': cidr_ip,
Tony Mackcdb85aa2013-05-02 15:09:45 -0400202 'dns_nameservers': ['8.8.8.8', '8.8.4.4'],
Tony Mack48952032013-04-12 11:49:34 -0400203 'allocation_pools': allocation_pools}}
204 subnet = self.shell.quantum.create_subnet(subnet)['subnet']
Tony Mack0211f1b2013-04-04 23:56:24 -0400205
206 # TODO: Add route to external network
207 # e.g. # route add -net 10.0.3.0/24 dev br-ex gw 10.100.0.5
208 return subnet
209
Tony Mack48952032013-04-12 11:49:34 -0400210 def update_subnet(self, id, fields):
211 return self.shell.quantum.update_subnet(id, fields)
212
Tony Mack0211f1b2013-04-04 23:56:24 -0400213 def delete_subnet(self, id):
Tony Mackfd24d0d2013-04-14 00:59:17 -0400214 #return self.shell.quantum.delete_subnet(id=id)
215 # inefficient but fault tolerant
216 subnets = self.shell.quantum.list_subnets()['subnets']
217 for subnet in subnets:
218 if subnet['id'] == id:
Tony Mack94c6ea02013-04-16 21:41:50 -0400219 self.delete_subnet_ports(subnet['id'])
Tony Mack31d34132013-04-15 00:02:06 -0400220 self.shell.quantum.delete_subnet(id)
Tony Mackfd24d0d2013-04-14 00:59:17 -0400221 return
Tony Mack0211f1b2013-04-04 23:56:24 -0400222
223 def create_keypair(self, name, key):
Tony Mackc2a1c7c2013-04-09 13:06:34 -0400224 keys = self.shell.nova.keypairs.findall(name=name)
Tony Mack0211f1b2013-04-04 23:56:24 -0400225 if keys:
Tony Mack52cb9302013-04-09 12:25:35 -0400226 key = keys[0]
227 else:
Tony Mackc2a1c7c2013-04-09 13:06:34 -0400228 key = self.shell.nova.keypairs.create(name=name, public_key=key)
Tony Mack52cb9302013-04-09 12:25:35 -0400229 return key
Tony Mack0211f1b2013-04-04 23:56:24 -0400230
Tony Mack759b57a2013-04-14 21:03:31 -0400231 def delete_keypair(self, id):
232 keys = self.shell.nova.keypairs.findall(id=id)
Tony Mack0211f1b2013-04-04 23:56:24 -0400233 for key in keys:
Tony Mackc2a1c7c2013-04-09 13:06:34 -0400234 self.shell.nova.keypairs.delete(key)
Tony Mackfd24d0d2013-04-14 00:59:17 -0400235 return 1
Tony Mack7823b892013-03-29 20:35:26 -0400236
Tony Macke7e304f2013-04-30 18:18:03 -0400237 def spawn_instance(self, name, key_name=None, hostname=None, image_id=None, security_group=None, pubkeys=[]):
238 flavor_name = self.config.nova_default_flavor
239 flavor = self.shell.nova.flavors.find(name=flavor_name)
Tony Mack221957d2013-04-13 19:08:34 -0400240 #if not image:
241 # image = self.config.nova_default_imave
Tony Mack01942f52013-03-26 14:26:40 -0400242 if not security_group:
243 security_group = self.config.nova_default_security_group
244
Tony Mack36538ab2013-05-01 17:24:46 -0400245 #authorized_keys = "\n".join(pubkeys)
246 #files = {'/root/.ssh/authorized_keys': authorized_keys}
247 files = {}
Tony Mack01942f52013-03-26 14:26:40 -0400248
Tony Mack7823b892013-03-29 20:35:26 -0400249 hints = {}
Tony Mack79b28ca2013-04-15 21:47:45 -0400250 availability_zone = None
Tony Mack7823b892013-03-29 20:35:26 -0400251 if hostname:
Tony Mack79b28ca2013-04-15 21:47:45 -0400252 availability_zone = 'nova:%s' % hostname
Tony Mack7823b892013-03-29 20:35:26 -0400253 server = self.shell.nova.servers.create(
254 name=name,
255 key_name = key_name,
Tony Macke7e304f2013-04-30 18:18:03 -0400256 flavor=flavor.id,
Tony Mack7823b892013-03-29 20:35:26 -0400257 image=image_id,
258 security_group = security_group,
259 files=files,
Tony Mack79b28ca2013-04-15 21:47:45 -0400260 scheduler_hints=hints,
261 availability_zone=availability_zone)
Tony Mack7823b892013-03-29 20:35:26 -0400262 return server
Tony Mack01942f52013-03-26 14:26:40 -0400263
Tony Mackcdec0902013-04-15 00:38:49 -0400264 def destroy_instance(self, id):
265 servers = self.shell.nova.servers.findall(id=id)
Tony Mack01942f52013-03-26 14:26:40 -0400266 for server in servers:
Tony Mackcdec0902013-04-15 00:38:49 -0400267 self.shell.nova.servers.delete(server)
smbaker6ada7bf2013-04-30 18:15:48 -0700268
269 def update_instance_metadata(self, id, metadata):
270 servers = self.shell.nova.servers.findall(id=id)
271 for server in servers:
272 self.shell.nova.servers.set_meta(server, metadata)
273 # note: set_meta() returns a broken Server() object. Don't try to
274 # print it in the shell or it will fail in __repr__.
275
276 def delete_instance_metadata(self, id, metadata):
277 # note: metadata is a dict. Only the keys matter, not the values.
278 servers = self.shell.nova.servers.findall(id=id)
279 for server in servers:
280 self.shell.nova.servers.delete_meta(server, metadata)
281