1 # -*- coding: utf-8 -*-
3 # This file is part of Karesansui.
5 # Copyright (C) 2009-2010 HDE, Inc.
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License
9 # as published by the Free Software Foundation; either version 2
10 # of the License, or (at your option) any later version.
14 import simplejson as json
17 from karesansui.lib.rest import Rest, auth
18 from karesansui.lib.const import VIRT_COMMAND_DELETE_NETWORK, VIRT_COMMAND_UPDATE_NETWORK
19 from karesansui.db.access.machine import findbyhost1
20 from karesansui.db.access._2pysilhouette import jobgroup_findbyuniqkey
21 from karesansui.lib.virt.virt import KaresansuiVirtException, \
22 KaresansuiVirtConnection
23 from karesansui.db.access._2pysilhouette import save_job_collaboration
24 from karesansui.db.access.machine2jobgroup import new as m2j_new
26 from pysilhouette.command import dict2command
27 from karesansui.db.model._2pysilhouette import Job, JobGroup
29 from karesansui.lib.checker import Checker, \
30 CHECK_EMPTY, CHECK_VALID, CHECK_LENGTH, \
31 CHECK_CHAR, CHECK_MIN, CHECK_MAX, CHECK_ONLYSPACE, \
34 from karesansui.lib.utils import is_param, is_empty, available_virt_uris
36 def validates_network(obj, network_name=None):
45 checker.add_error(_('Specify network name.'))
47 if not is_param(obj.input, 'cidr'):
49 checker.add_error(_('Specify bridge IP address for the network.'))
51 check = checker.check_ipaddr(
52 _('Bridge IP Address/Netmask'),
54 CHECK_EMPTY | CHECK_VALID,
57 if not is_param(obj.input, 'bridge'):
59 checker.add_error(_('Specify bridge name to create for the network.'))
61 check = checker.check_netdev_name(
62 _('Bridge Device Name'),
64 CHECK_EMPTY | CHECK_VALID,
67 A = is_param(obj.input, 'dhcp_start')
68 B = is_param(obj.input, 'dhcp_end')
69 #if not ( ((not A) and (not B)) or (A and B)):
72 checker.add_error(_('Specify both %s and %s') % (_('DHCP Start Address'), _('DHCP End Address')))
74 if is_param(obj.input, 'dhcp_start'):
75 check = checker.check_ipaddr(
76 _('DHCP Start Address'),
78 CHECK_EMPTY | CHECK_ONLYSPACE | CHECK_VALID,
81 if is_param(obj.input, 'dhcp_end'):
82 check = checker.check_ipaddr(
83 _('DHCP End Address'),
85 CHECK_EMPTY | CHECK_ONLYSPACE | CHECK_VALID,
88 check = checker.check_if_ips_are_in_network(
89 [ _('DHCP Start Address'), _('DHCP End Address'), _('Bridge IP Address/Netmask')],
90 [obj.input.dhcp_start, obj.input.dhcp_end],
92 CHECK_VALID | CHECK_UNIQUE) and check
94 check = checker.check_ip_range(
95 [ _('DHCP Start Address'), _('DHCP End Address'), _('Bridge IP Address/Netmask')],
96 [obj.input.dhcp_start, obj.input.dhcp_end, obj.input.cidr],
97 CHECK_VALID) and check
99 check = checker.check_virt_network_address_conflict(
100 _('Bridge IP Address/Netmask'),
102 [network_name], # names to ignore
103 CHECK_VALID) and check
105 if is_param(obj.input, 'forward_mode'):
106 check = checker.check_forward_mode(
108 obj.input.forward_mode,
112 obj.view.alert = checker.errors
115 class HostBy1NetworkBy1(Rest):
117 def _GET(self, *param, **params):
118 host_id = self.chk_hostby1(param)
119 if host_id is None: return web.notfound()
121 network_name = param[1]
122 if not (network_name and host_id):
123 return web.badrequest()
125 kvc = KaresansuiVirtConnection()
128 network = kvc.search_kvn_networks(network_name)[0] # throws KaresansuiVirtException
129 info = network.get_info()
130 except KaresansuiVirtException, e:
132 self.logger.debug("Network not found. name=%s" % network_name)
133 return web.notfound()
137 cidr = '%s/%s' % (info['ip']['address'], info['ip']['netmask'])
138 network = dict(name=info['name'],
140 dhcp_start=info['dhcp']['start'],
141 dhcp_end=info['dhcp']['end'],
142 forward_dev=info['forward']['dev'],
143 forward_mode=info['forward']['mode'],
144 bridge=info['bridge']['name'],
146 self.view.info = info
147 self.view.network = network
151 def _PUT(self, *param, **params):
152 host_id = self.chk_hostby1(param)
153 if host_id is None: return web.notfound()
155 network_name = param[1]
157 self.logger.debug("Network update failed. Network not found.")
158 return web.notfound("Network not found.")
160 if not validates_network(self, network_name=network_name):
161 self.logger.debug("Network update failed. Did not validate.")
162 return web.badrequest(self.view.alert)
164 cidr = self.input.cidr
165 dhcp_start = self.input.dhcp_start
166 dhcp_end = self.input.dhcp_end
167 bridge = self.input.bridge
168 forward_mode = getattr(self.input, 'forward_mode', '')
171 autostart = self.input.autostart
176 # spin off update job
178 options = {'name' : network_name,
180 'dhcp-start': dhcp_start,
181 'dhcp-end' : dhcp_end,
182 'bridge-name' : bridge,
183 'forward-mode' : forward_mode,
184 'autostart' : autostart,
187 self.logger.debug('spinning off network_update_job options=%s' % (options))
189 host = findbyhost1(self.orm, host_id)
192 "%s/%s" % (karesansui.config['application.bin.dir'], VIRT_COMMAND_UPDATE_NETWORK), options)
195 _jobgroup = JobGroup('Update network: %s' % network_name, karesansui.sheconf['env.uniqkey'])
196 _jobgroup.jobs.append(Job('Update network', 0, _cmd))
198 _machine2jobgroup = m2j_new(machine=host,
200 uniq_key=karesansui.sheconf['env.uniqkey'],
201 created_user=self.me,
202 modified_user=self.me,
205 save_job_collaboration(self.orm,
206 self.pysilhouette.orm,
211 self.logger.debug('(Update network) Job group id==%s', _jobgroup.id)
212 url = '%s/job/%s.part' % (web.ctx.home, _jobgroup.id)
213 self.logger.debug('Returning Location: %s' % url)
215 return web.accepted(url=url)
218 def _DELETE(self, *param, **params):
219 host_id = self.chk_hostby1(param)
220 if host_id is None: return web.notfound()
222 network_name = param[1]
224 self.logger.debug("Network delete failed. Network not found.")
225 return web.notfound("Network not found.")
227 if network_name == 'default':
228 self.logger.debug('Network delete failed. Target network is "default".')
229 return web.badrequest('Target network "default" can not deleted.')
231 host = findbyhost1(self.orm, host_id)
234 options['name'] = network_name
236 "%s/%s" % (karesansui.config['application.bin.dir'], VIRT_COMMAND_DELETE_NETWORK), options)
239 _jobgroup = JobGroup('Delete network: %s' % network_name, karesansui.sheconf['env.uniqkey'])
240 _jobgroup.jobs.append(Job('Delete network', 0, _cmd))
242 _machine2jobgroup = m2j_new(machine=host,
244 uniq_key=karesansui.sheconf['env.uniqkey'],
245 created_user=self.me,
246 modified_user=self.me,
249 save_job_collaboration(self.orm,
250 self.pysilhouette.orm,
255 self.logger.debug('(Delete network) Job group id==%s', _jobgroup.id)
256 url = '%s/job/%s.part' % (web.ctx.home, _jobgroup.id)
257 self.logger.debug('Returning Location: %s' % url)
259 return web.accepted()
262 '/host/(\d+)/network/([^\./]+)[/]?(\.html|\.part|\.json)?$', HostBy1NetworkBy1,