Class: Application

Inherits:
Merb::Controller
  • Object
show all
Includes:
Chef::Mixin::Checksum
Defined in:
app/controllers/application.rb

Instance Method Summary collapse

Instance Method Details

#access_deniedObject



106
107
108
109
110
111
112
113
114
# File 'app/controllers/application.rb', line 106

def access_denied
  case content_type
  when :html
    store_location
    redirect url(:users_login), :message => { :error => "You don't have access to that, please login."}
  else
    raise Unauthorized, "You must authenticate first!"
  end
end

#append_tree(name, html, node, count, parent) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'app/controllers/application.rb', line 175

def append_tree(name, html, node, count, parent)
  to_do = node
  #to_do = node.kind_of?(Chef::Node) ? node.attribute : node
  Chef::Log.debug("I have #{to_do.inspect}")
  to_do.sort{ |a,b| a[0] <=> b[0] }.each do |key, value|
    Chef::Log.debug("I am #{key.inspect} #{value.inspect}")
    to_send = Array.new
    count += 1
    is_parent = false
    local_html = ""
    local_html << "<tr id='#{name}-#{count}' class='collapsed #{name}"
    if parent != 0
      local_html << " child-of-#{name}-#{parent}' style='display: none;'>"
    else
      local_html << "'>"
    end
    local_html << "<td class='table-key'><span toggle='#{name}-#{count}'/>#{key}</td>"
    case value
    when Hash
      is_parent = true
      local_html << "<td></td>"
      p = count
      to_send << Proc.new { append_tree(name, html, value, count, p) }
    when Array
      is_parent = true
      local_html << "<td></td>"
      as_hash = {}
      value.each_index { |i| as_hash[i] = value[i] }
      p = count
      to_send << Proc.new { append_tree(name, html, as_hash, count, p) }
    else
      local_html << "<td><div class='json-attr'>#{value}</div></td>"
    end
    local_html << "</tr>"
    local_html.sub!(/class='collapsed/, 'class=\'collapsed parent') if is_parent
    local_html.sub!(/<span/, "<span class='expander'") if is_parent
    html << local_html
    to_send.each { |s| count = s.call }
    count += to_send.length
  end
  count
end

#bad_request?(exception) ⇒ Boolean

Returns:

  • (Boolean)


289
290
291
# File 'app/controllers/application.rb', line 289

def bad_request?(exception)
  exception.kind_of?(Net::HTTPServerException) && exception.message =~ /400/
end

#binary?(file) ⇒ Boolean

Returns:

  • (Boolean)


243
244
245
246
# File 'app/controllers/application.rb', line 243

def binary?(file)
  s = (File.read(file, File.stat(file).blksize) || "")
  s.empty? || ( s.count( "^ -~", "^\r\n" ).fdiv(s.size) > 0.3 || s.index( "\x00" ))
end

#build_tree(name, node) ⇒ Object



165
166
167
168
169
170
171
172
173
# File 'app/controllers/application.rb', line 165

def build_tree(name, node)
  html = "<table id='#{name}' class='tree table'>"
  html << "<tr><th class='first'>Attribute</th><th class='last'>Value</th></tr>"
  count = 0
  parent = 0
  append_tree(name, html, node, count, parent)
  html << "</table>"
  html
end

#can_edit_admin?Boolean

whether or not the user should be able to edit a user’s admin status

Returns:

  • (Boolean)


86
87
88
89
# File 'app/controllers/application.rb', line 86

def can_edit_admin?
  return false unless is_admin? && !is_last_admin?
  true
end

#cleanup_sessionObject



52
53
54
# File 'app/controllers/application.rb', line 52

def cleanup_session
  [:user,:level, :environment].each { |n| session.delete(n) }
end

#conflict?(exception) ⇒ Boolean

Returns:

  • (Boolean)


277
278
279
# File 'app/controllers/application.rb', line 277

def conflict?(exception)
  exception.kind_of?(Net::HTTPServerException) && exception.message =~ /409/
end

#convert_newline_to_br(string) ⇒ Object



266
267
268
# File 'app/controllers/application.rb', line 266

def convert_newline_to_br(string)
  string.to_s.gsub(/\n/, '<br />') unless string.nil?
end

#determine_name(type, object) ⇒ Object

for showing search result



253
254
255
256
257
258
259
260
# File 'app/controllers/application.rb', line 253

def determine_name(type, object)
  case type
  when :node, :role, :client, :environment
    object.name
  else
    params[:id]
  end
end

#forbidden?(exception) ⇒ Boolean

Returns:

  • (Boolean)


281
282
283
# File 'app/controllers/application.rb', line 281

def forbidden?(exception)
  exception.kind_of?(Net::HTTPServerException) && exception.message =~ /403/
end

#format_exception(exception) ⇒ Object



270
271
272
273
274
275
# File 'app/controllers/application.rb', line 270

def format_exception(exception)
  require 'pp'
  pretty_params = StringIO.new
  PP.pp({:request_params => params}, pretty_params)
  "#{exception.class.name}: #{exception.message}\n#{pretty_params.string}\n#{exception.backtrace.join("\n")}"
end

#is_admin?Boolean

Returns:

  • (Boolean)


66
67
68
69
# File 'app/controllers/application.rb', line 66

def is_admin?
  user = Chef::WebUIUser.load(session[:user])
  user.admin?
end

#is_last_admin?Boolean

return true if there is only one admin left, false otherwise

Returns:

  • (Boolean)


72
73
74
75
76
77
78
79
80
81
82
83
# File 'app/controllers/application.rb', line 72

def is_last_admin?
  count = 0
  users = Chef::WebUIUser.list
  users.each do |u, url|
    user = Chef::WebUIUser.load(u)
    if user.admin
      count = count + 1
      return false if count == 2
    end
  end
  true
end

#list_available_recipes_for(environment) ⇒ Object



262
263
264
# File 'app/controllers/application.rb', line 262

def list_available_recipes_for(environment)
  Chef::Environment.load_filtered_recipe_list(environment).sort!
end

#load_cookbook_segment(cookbook_id, segment) ⇒ Object

Load a cookbook and return a hash with a list of all the files of a given segment (attributes, recipes, definitions, libraries)

Parameters

cookbook_id<String>

The cookbook to load

segment<Symbol>

:attributes, :recipes, :definitions, :libraries

Returns

<Hash>

A hash consisting of the short name of the file in :name, and the full path

to the file in :file.

Raises:

  • (NotFound)


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/controllers/application.rb', line 130

def load_cookbook_segment(cookbook_id, segment)
  r = Chef::REST.new(Chef::Config[:chef_server_url])
  cookbook = r.get_rest("cookbooks/#{cookbook_id}")

  raise NotFound unless cookbook

  files_list = segment_files(segment, cookbook)

  files = Hash.new
  files_list.each do |f|
    files[f['name']] = {
      :name => f["name"],
      :file => f["uri"],
    }
  end
  files
end

#load_environmentsObject



116
117
118
# File 'app/controllers/application.rb', line 116

def load_environments
  @environments = Chef::Environment.list.keys.sort
end

#load_session_userObject



46
47
48
49
50
# File 'app/controllers/application.rb', line 46

def load_session_user
  Chef::WebUIUser.load(session[:user])
rescue
  raise NotFound, "Cannot find User #{session[:user]}, maybe it got deleted by an Administrator."
end

#login_requiredObject

Check if the user is logged in and if the user still exists



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'app/controllers/application.rb', line 31

def 
 if session[:user]
   begin
     load_session_user
   rescue
     
   else
     return session[:user]
   end
 else
   self.store_location
   throw(:halt, :access_denied)
 end
end

#logout_and_redirect_to_loginObject



56
57
58
59
60
# File 'app/controllers/application.rb', line 56

def 
  cleanup_session
  @user = Chef::WebUIUser.new
  redirect(url(:users_login), {:message => { :error => $! }, :permanent => true})
end

#not_found?(exception) ⇒ Boolean

Returns:

  • (Boolean)


285
286
287
# File 'app/controllers/application.rb', line 285

def not_found?(exception)
  exception.kind_of?(Net::HTTPServerException) && exception.message =~ /404/
end

#redirect_back_or_default(default) ⇒ Object

Redirect to the URI stored by the most recent store_location call or to the passed default.



100
101
102
103
104
# File 'app/controllers/application.rb', line 100

def redirect_back_or_default(default)
  loc = session[:return_to] || default
  session[:return_to] = nil
  redirect loc
end

#require_adminObject



62
63
64
# File 'app/controllers/application.rb', line 62

def require_admin
  raise AdminAccessRequired unless is_admin?
end

#segment_files(segment, cookbook) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'app/controllers/application.rb', line 148

def segment_files(segment, cookbook)
  files_list = nil
  case segment
  when :attributes
    files_list = cookbook["attributes"]
  when :recipes
    files_list = cookbook["recipes"]
  when :definitions
    files_list = cookbook["definitions"]
  when :libraries
    files_list = cookbook["libraries"]
  else
    raise ArgumentError, "segment must be one of :attributes, :recipes, :definitions or :libraries"
  end
  files_list
end

#show_plain_file(file_url) ⇒ Object



229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'app/controllers/application.rb', line 229

def show_plain_file(file_url)
  Chef::Log.debug("fetching file from '#{file_url}' for highlighting")
  r = Chef::REST.new(Chef::Config[:chef_server_url])
  r.fetch(file_url) do |tempfile|
    if binary?(tempfile.path)
      return "Binary file not shown"
    elsif ((File.size(tempfile.path) / (1048576)) > 5)
      return "File too large to display"
    else
      return IO.read(tempfile.path)
    end
  end
end

#store_locationObject

Store the URI of the current request in the session.

We can return to this location by calling #redirect_back_or_default.



94
95
96
# File 'app/controllers/application.rb', line 94

def store_location
  session[:return_to] = request.uri
end

#str_to_bool(str) ⇒ Object



248
249
250
# File 'app/controllers/application.rb', line 248

def str_to_bool(str)
  str =~ /true/ ? true : false
end

#syntax_highlight(file_url) ⇒ Object



218
219
220
221
222
223
224
225
226
227
# File 'app/controllers/application.rb', line 218

def syntax_highlight(file_url)
  Chef::Log.debug("fetching file from '#{file_url}' for highlighting")
  r = Chef::REST.new(Chef::Config[:chef_server_url])
  highlighted_file = nil
  r.fetch(file_url) do |tempfile|
    tokens = CodeRay.scan_file(tempfile.path, :ruby)
    highlighted_file = CodeRay.encode_tokens(tokens, :span)
  end
  highlighted_file
end