tests limits for beeing nil
[opensuse:yast-web-client.git] / plugins / status / app / controllers / status_controller.rb
1 require 'yast/service_resource'
2
3 class StatusController < ApplicationController
4   before_filter :login_required
5   layout "main"
6
7   private
8   def client_permissions
9     @client = YaST::ServiceResource.proxy_for('org.opensuse.yast.system.status')
10     unless @client
11       flash[:notice] = _("Invalid session, please login again.")
12       redirect_to( logout_path ) and return
13     end
14     @permissions = @client.permissions
15   end
16
17   def write_data_group(label, group, metric_name, limits=nil)
18     data_list = Array.new
19     divisor = (group == "memory")? 1024*1024 : 1 # take MByte for the value
20     count = 0
21     data_list = label.map{ |v| count+=1; [count,v.to_f/divisor]}
22     @data_group[group].merge!({metric_name => data_list})
23     #TODO: implement maximum and minimum format
24     if limits
25       count = 0
26       @limits_list[label] = Hash.new
27       @limits_list[label].merge!({:min => limits["min"].map{ |l| count+=1; [count,l.to_f/divisor]}}) if limits["min"]
28       @limits_list[label].merge!({:max => limits["max"].map{ |l| count+=1; [count,l.to_f/divisor]}}) if limits["max"]
29     end
30 #    @data["/#{group}/#{metric_name}/..."] = data_list
31   end
32
33   def create_data_map(tree)
34     tree.attributes["metric"].each{ |metric|
35       metric_name = metric.name
36       group = metric.metricgroup
37       @data_group[group] ||= Hash.new
38       interval = metric.interval #TODO: not used yet
39       starttime = metric.starttime
40       case metric.attributes["label"]
41       when YaST::ServiceResource::Proxies::Status::Metric::Label # one label
42         limits = metric.attributes["limits"].attributes if metric.attributes.has_key? "limits"
43         write_data_group(metric.attributes["label"].attributes["values"], group, metric_name, limits)
44       when Array # several label
45         metric.attributes["label"].each{ |l|
46           limits = l.attributes["limits"].attributes if l.attributes.has_key? "limits"
47           write_data_group(l.attributes["values"], group, metric_name, limits)
48       }
49       end
50     }
51   end
52
53   def create_data
54     @data = Hash.new
55     @limits = Hash.new
56     @limits_list = Hash.new
57     @data_group = Hash.new
58     status = []
59     begin
60       till = Time.new
61       from = till - 300 #last 5 minutes
62 #puts File.read(@client.find(:dummy_param, :params => { :start => from.to_i.to_s, :stop => till.to_i.to_s }))
63       status = @client.find(:dummy_param, :params => { :start => from.to_i.to_s, :stop => till.to_i.to_s })
64
65       rescue ActiveResource::ClientError => e
66         flash[:error] = YaST::ServiceResource.error(e)
67         return false
68     end
69     create_data_map status
70 =begin
71     #grouping graphs to memory, cpu,...
72     @data.each do |key, list_value|
73       if @limits.has_key?(key)
74         graph_list = []
75         key_split = key.split("/")
76         for i in 0..list_value.size-1 do
77           if key_split.size>1 && key_split[1]=="memory" # take MByte for the value
78             graph_list << [i,@limits[key]["value"]/1024/1024]
79           else
80             graph_list << [i,@limits[key]["value"]]
81           end
82         end
83         @limits_list[key] = graph_list
84       end
85
86       key_split = key.split("/")
87       if key_split.size > 1
88         group_map = {}
89       end
90     end
91 =end
92     # puts @data_group.inspect
93     true
94   end
95
96   #removing logging data and add limits which are defined in params
97   def create_save_data(status, params, label = "") #TODO: customize for new xml format
98     status.each do |key, value|
99      if key.start_with?("values")
100        status.delete(key)
101      elsif
102        next_label = label+ "/" + key
103        create_save_data(value, params, next_label) if value.is_a? Hash
104      end
105     end
106     if params.has_key?(label+"/value")
107       limit = Hash.new
108       key_split = label.split("/")
109       if key_split.size>1 && key_split[1]=="memory" # MByte for the value --> change it to Byte
110         limit["value"] = params[label+"/value"].to_f*1024*1024
111       else
112         limit["value"] = params[label+"/value"]
113       end
114       limit["maximum"] = params[label+"/maximum"] == "true"?true:false
115       status["limit"] = limit
116     end
117     return status
118   end
119
120  # Initialize GetText and Content-Type.
121   init_gettext "yast_webclient_status"
122
123   public
124
125   def initialize
126   end
127
128   def edit
129     return unless client_permissions
130     create_data
131   end
132
133   def index
134     return unless client_permissions
135     create_data
136     @limit_hits = []
137     @data_group.each do |key, map|
138       map.each do |graph_key, list_value|
139         limit_key = "/#{key}/#{graph_key}"
140         if  @limits_list.has_key?(limit_key)
141           cmp_value = @limits_list[limit_key][0][1] #take thatone cause it has already the right format
142                                                  #( e.g. MByte for memory)
143           list_value.each do |value|
144             if (@limits[limit_key]["maximum"] && value[1]>= cmp_value) ||
145                (!@limits[limit_key]["maximum"] && value[1]<= cmp_value)
146               @limit_hits << limit_key
147               break
148             end
149           end
150         end
151       end
152     end
153     logger.debug "limits reached for #{@limit_hits.inspect}"
154   end
155
156
157   def show_summary
158     return unless client_permissions
159     unless create_data
160       erase_redirect_results #reset all redirects
161       erase_render_results
162       error = flash[:error]
163       flash.clear #no flash from load_proxy
164       render :partial => "status_summary", :locals => { :status => nil, :error => error }
165       return false
166     end
167     status = ""
168     @data_group.each do |key, map|
169       error_found = false
170       map.each do |graph_key, list_value|
171         limit_key = "/#{key}/#{graph_key}"
172         if  @limits_list.has_key?(limit_key)
173           cmp_value = @limits_list[limit_key][0][1] #take thatone cause it has already the right format
174                                                  #( e.g. MByte for memory)
175           list_value.each do |value|
176             if (@limits[limit_key]["maximum"] && value[1]>= cmp_value) ||
177                (!@limits[limit_key]["maximum"] && value[1]<= cmp_value)
178               error_found = true
179               break
180             end
181           end
182         end
183       end
184       if error_found
185         status += "; " unless status.blank?
186         if key == "df"
187           status += _("Disk free limits exceeded")
188         else
189           status += key.capitalize + " " + _("limits exceeded")
190         end
191       end
192     end
193
194     render :partial => "status_summary", :locals => { :status => status, :error => nil }
195   end
196
197   def save
198     return unless client_permissions
199     begin
200       till = Time.new
201       from = till - 300 #last 5 minutes
202       status = @client.find(:dummy_param, :params => {  :start => from.to_i.to_s, :stop => till.to_i.to_s })
203
204       rescue ActiveResource::ClientError => e
205         flash[:error] = YaST::ServiceResource.error(e)
206         redirect_to :controller=>"status", :action=>"edit"
207         return false
208     end
209
210     save_hash = create_save_data(Hash.from_xml(status.to_xml)["status"], params)
211     logger.debug "writing #{save_hash.inspect}"
212
213     save_status = @client.new()
214     save_status.load(save_hash)
215
216     success = true
217     begin
218       save_status.save
219       logger.debug "limits have been written"
220       flash[:notice] = _("Limits have been written.")
221     rescue ActiveResource::ClientError => e
222        flash[:error] = YaST::ServiceResource.error(e)
223        ExceptionLogger.log_exception e
224        success = false
225     end
226     if success
227       redirect_to :controller=>"status", :action=>"index"
228     else
229       redirect_to :controller=>"status", :action=>"edit"
230     end
231   end
232
233 end