OSDN Git Service

Remove pdb
[karesansui/karesansui.git] / karesansui / gadget / hostby1networkby1.py
1 # -*- coding: utf-8 -*-
2 #
3 # This file is part of Karesansui.
4 #
5 # Copyright (C) 2009-2010 HDE, Inc.
6 #
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.
11 #
12
13 import web
14 import simplejson as json
15
16 import karesansui
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
25
26 from pysilhouette.command import dict2command
27 from karesansui.db.model._2pysilhouette import Job, JobGroup
28
29 from karesansui.lib.checker import Checker, \
30     CHECK_EMPTY, CHECK_VALID, CHECK_LENGTH, \
31     CHECK_CHAR, CHECK_MIN, CHECK_MAX, CHECK_ONLYSPACE, \
32     CHECK_UNIQUE
33
34 from karesansui.lib.utils import is_param, is_empty, available_virt_uris
35
36 def validates_network(obj, network_name=None):
37     checker = Checker()
38     check = True
39
40     _ = obj._
41     checker.errors = []
42
43     if not network_name:
44         check = False
45         checker.add_error(_('Specify network name.'))
46
47     if not is_param(obj.input, 'cidr'):
48         check = False
49         checker.add_error(_('Specify bridge IP address for the network.'))
50     else:
51         check = checker.check_ipaddr(
52                 _('Bridge IP Address/Netmask'),
53                 obj.input.cidr,
54                 CHECK_EMPTY | CHECK_VALID,
55                 ) and check
56
57     if not is_param(obj.input, 'bridge'):
58         check = False
59         checker.add_error(_('Specify bridge name to create for the network.'))
60     else:
61         check = checker.check_netdev_name(
62                 _('Bridge Device Name'),
63                 obj.input.bridge,
64                 CHECK_EMPTY | CHECK_VALID,
65                 ) and check
66
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)):
70     if not (A and B):
71         check = False
72         checker.add_error(_('Specify both %s and %s') % (_('DHCP Start Address'), _('DHCP End Address')))
73
74     if is_param(obj.input, 'dhcp_start'):
75         check = checker.check_ipaddr(
76                 _('DHCP Start Address'),
77                 obj.input.dhcp_start,
78                 CHECK_EMPTY | CHECK_ONLYSPACE | CHECK_VALID,
79                 ) and check
80
81     if is_param(obj.input, 'dhcp_end'):
82         check = checker.check_ipaddr(
83                 _('DHCP End Address'),
84                 obj.input.dhcp_end,
85                 CHECK_EMPTY | CHECK_ONLYSPACE | CHECK_VALID,
86                 ) and check
87
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],
91                             obj.input.cidr,
92                             CHECK_VALID | CHECK_UNIQUE) and check
93
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
98
99     check = checker.check_virt_network_address_conflict(
100                             _('Bridge IP Address/Netmask'),
101                             obj.input.cidr,
102                             [network_name],   # names to ignore
103                             CHECK_VALID) and check
104
105     if is_param(obj.input, 'forward_mode'):
106         check = checker.check_forward_mode(
107                 _('Forward Mode'),
108                 obj.input.forward_mode,
109                 CHECK_VALID,
110                 ) and check
111
112     obj.view.alert = checker.errors
113     return check
114
115 class HostBy1NetworkBy1(Rest):
116     @auth
117     def _GET(self, *param, **params):
118         host_id = self.chk_hostby1(param)
119         if host_id is None: return web.notfound()
120
121         network_name = param[1]
122         if not (network_name and host_id):
123             return web.badrequest()
124
125         kvc = KaresansuiVirtConnection()
126         try:
127             try:
128                 network = kvc.search_kvn_networks(network_name)[0] # throws KaresansuiVirtException
129                 info = network.get_info()
130             except KaresansuiVirtException, e:
131                 # network not found
132                 self.logger.debug("Network not found. name=%s" % network_name)
133                 return web.notfound()
134         finally:
135             kvc.close()
136
137         cidr = '%s/%s' % (info['ip']['address'], info['ip']['netmask'])
138         network = dict(name=info['name'],
139                        cidr=cidr,
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'],
145                        )
146         self.view.info = info
147         self.view.network = network
148         return True
149
150     @auth
151     def _PUT(self, *param, **params):
152         host_id = self.chk_hostby1(param)
153         if host_id is None: return web.notfound()
154
155         network_name = param[1]
156         if not network_name:
157             self.logger.debug("Network update failed. Network not found.")
158             return web.notfound("Network not found.")
159
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)
163
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', '')
169
170         try:
171             autostart = self.input.autostart
172         except:
173             autostart = "no"
174
175         #
176         # spin off update job
177         #
178         options = {'name' : network_name,
179                    'cidr': cidr,
180                    'dhcp-start': dhcp_start,
181                    'dhcp-end' : dhcp_end,
182                    'bridge-name' : bridge,
183                    'forward-mode' : forward_mode,
184                    'autostart' : autostart,
185                    }
186
187         self.logger.debug('spinning off network_update_job options=%s' % (options))
188
189         host = findbyhost1(self.orm, host_id)
190
191         _cmd = dict2command(
192             "%s/%s" % (karesansui.config['application.bin.dir'], VIRT_COMMAND_UPDATE_NETWORK), options)
193
194         # Job Registration
195         _jobgroup = JobGroup('Update network: %s' % network_name, karesansui.sheconf['env.uniqkey'])
196         _jobgroup.jobs.append(Job('Update network', 0, _cmd))
197
198         _machine2jobgroup = m2j_new(machine=host,
199                                     jobgroup_id=-1,
200                                     uniq_key=karesansui.sheconf['env.uniqkey'],
201                                     created_user=self.me,
202                                     modified_user=self.me,
203                                     )
204
205         save_job_collaboration(self.orm,
206                                self.pysilhouette.orm,
207                                _machine2jobgroup,
208                                _jobgroup,
209                                )
210
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)
214
215         return web.accepted(url=url)
216
217     @auth
218     def _DELETE(self, *param, **params):
219         host_id = self.chk_hostby1(param)
220         if host_id is None: return web.notfound()
221
222         network_name = param[1]
223         if not network_name:
224             self.logger.debug("Network delete failed. Network not found.")
225             return web.notfound("Network not found.")
226
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.')
230
231         host = findbyhost1(self.orm, host_id)
232
233         options = {}
234         options['name'] = network_name
235         _cmd = dict2command(
236             "%s/%s" % (karesansui.config['application.bin.dir'], VIRT_COMMAND_DELETE_NETWORK), options)
237
238         # Job Registration
239         _jobgroup = JobGroup('Delete network: %s' % network_name, karesansui.sheconf['env.uniqkey'])
240         _jobgroup.jobs.append(Job('Delete network', 0, _cmd))
241
242         _machine2jobgroup = m2j_new(machine=host,
243                                     jobgroup_id=-1,
244                                     uniq_key=karesansui.sheconf['env.uniqkey'],
245                                     created_user=self.me,
246                                     modified_user=self.me,
247                                     )
248
249         save_job_collaboration(self.orm,
250                                self.pysilhouette.orm,
251                                _machine2jobgroup,
252                                _jobgroup,
253                                )
254
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)
258
259         return web.accepted()
260
261 urls = (
262     '/host/(\d+)/network/([^\./]+)[/]?(\.html|\.part|\.json)?$', HostBy1NetworkBy1,
263     )
264