handle non existing bootproto parameter (bnc#623461)
[opensuse:yast-web-client.git] / plugins / network / app / controllers / network_controller.rb
1 #--
2 # Copyright (c) 2009-2010 Novell, Inc.
3
4 # All Rights Reserved.
5
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of version 2 of the GNU General Public License
8 # as published by the Free Software Foundation.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, contact Novell, Inc.
17
18 # To contact Novell about this file by physical or electronic mail,
19 # you may find current contact information at www.novell.com
20 #++
21
22 class NetworkController < ApplicationController
23
24   before_filter :login_required
25   layout 'main'
26
27   private
28
29   # Initialize GetText and Content-Type.
30   init_gettext "webyast-network-ui" 
31
32   public
33   def initialize
34   end
35   
36   NETMASK_RANGE = 0..32
37   STATIC_BOOT_ID = "static"
38
39   # GET /network
40   def index
41     @ifcs = Interface.find :all
42     @iface = params[:interface]
43     unless @iface
44       ifc = @ifcs.find {|i| i.try(:bootproto)!=nil} || @ifcs[0]
45       @iface = ifc.id
46     end
47
48     ifc = Interface.find @iface
49     return false unless ifc
50
51     # TODO use rescue_from "AR::Base not found..."
52     # http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html
53     hn = Hostname.find :one
54     return false unless hn
55
56     dns = Dns.find :one
57     return false unless dns
58
59     rt = Route.find "default"
60     return false unless rt
61
62     # Only check permissions for one model, they should be the same
63     # and it is a UI hint only
64     # Can we also remove the resource lookups?
65     @permissions = Interface.permissions
66
67     # FIXME tests for YSRB
68
69     @conf_mode = ifc.bootproto
70     @conf_mode = STATIC_BOOT_ID if @conf_mode.blank?
71     if @conf_mode == STATIC_BOOT_ID
72       ipaddr = ifc.ipaddr
73     else
74       ipaddr = "/"
75     end
76     @ip, @netmask = ipaddr.split "/"
77     # when detect PREFIXLEN with leading "/"
78     if ifc.bootproto == STATIC_BOOT_ID && NETMASK_RANGE.include?(@netmask.to_i)
79       @netmask = "/"+@netmask
80     end    
81  
82     @name = hn.name
83     @domain = hn.domain
84     @nameservers = dns.nameservers
85     @searchdomains = dns.searches
86     @default_route = rt.via
87     @conf_modes = {_("Manual")=>STATIC_BOOT_ID, _("Automatic")=>"dhcp"}
88     @conf_modes[@conf_mode] =@conf_mode unless @conf_modes.has_value? @conf_mode
89     
90   end
91
92
93
94   # PUT /users/1
95   # PUT /users/1.xml
96   def update
97     dirty    = false
98     dirty_ifc = false
99     rt = Route.find "default"
100     return false unless rt
101     dirty = true unless rt.via == params["default_route"]
102     rt.via = params["default_route"]
103     logger.info "dirty after default routing: #{dirty}"
104
105     dns = Dns.find :one
106     return false unless dns
107     # Simply comparing empty array and nil would wrongly mark it dirty,
108     # so at first test emptiness
109     #FIXME repair it when spliting of param is ready
110     unless (dns.nameservers.empty? && params["nameservers"].blank?)
111       dirty = true unless dns.nameservers == (params["nameservers"]||"").split
112     end
113     unless (dns.searches.empty? && params["searchdomains"].blank?)
114       dirty = true unless dns.searches == (params["searchdomains"]||"").split
115     end
116     logger.info "dirty after  dns: #{dirty}"
117     # now the model contains arrays but for saving
118     # they need to be concatenated because we can't serialize them
119 # FIXME: params bellow should be arrays    
120     dns.nameservers = params["nameservers"]#.split
121     dns.searches    = params["searchdomains"]#.split
122
123     hn = Hostname.find :one
124     return false unless hn
125     dirty = true unless (hn.name == params["name"] && hn.domain == params["domain"])
126     logger.info "dirty after  hostname: #{dirty}"
127     hn.name   = params["name"]
128     hn.domain = params["domain"]
129
130     ifc = Interface.find params["interface"]
131     return false unless ifc
132     dirty_ifc = true unless (ifc.bootproto == params["conf_mode"])
133     logger.info "dirty after interface config: #{dirty}"
134     ifc.bootproto=params["conf_mode"]
135     if ifc.bootproto==STATIC_BOOT_ID
136       #ip addr is returned in another state then given, but restart of static address is not problem
137       if ((ifc.ipaddr||"").delete("/")!=params["ip"]+(params["netmask"]||"").delete("/"))
138         dirty_ifc = true
139         ifc.ipaddr=params["ip"]+"/"+params["netmask"].delete("/")
140       end
141     end
142    
143     begin
144       # this is not transaction!
145       # if any *.save failed, the previous will be applied
146       # FIXME JR: I think that if user choose dhcp not all settings should be written
147       if dirty||dirty_ifc
148         rt.save
149         dns.save
150         hn.save
151         # write interfaces (and therefore restart network) only when interface settings changed (bnc#579044)
152         if dirty_ifc
153           ifc.save
154         end
155       end
156 #write to avoid confusion, with another string
157       flash[:notice] = _('Network settings have been written.')
158     rescue ActiveResource::ServerError => e
159       response = Hash.from_xml(e.response.body)
160       if ( response["error"] && response["error"]["type"]=="NETWORK_ROUTE_ERROR")
161         flash[:error] = response["error"]["description"]
162         logger.warn e
163       else
164         raise
165       end
166     end
167
168     redirect_success
169   end
170 end