Class: ChefServerWebui::Application

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

Instance Method Summary collapse

Instance Method Details

#absolute_slice_url(slice_name, *args) ⇒ String

Generate the absolute url for a slice - takes the slice’s :path_prefix into account.

Examples:

absolute_slice_url(:awesome, :format => ‘html’)

absolute_slice_url(:forum, :posts, :format => ‘xml’)

Parameters:

  • slice_name (Symbol)

    The name of the slice - in identifier_sym format (underscored).

  • *args (Array[Symbol,Hash])

    There are several possibilities regarding arguments:

    • when passing a Hash only, the :default route of the current slice will be used

    • when a Symbol is passed, it’s used as the route name

    • a Hash with additional params can optionally be passed

Returns:

  • (String)

    A uri based on the requested slice.



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

def absolute_slice_url(slice_name, *args)
  options  = extract_options_from_args!(args) || {}
  protocol = options.delete(:protocol) || request.protocol
  host     = options.delete(:host) || request.host
  
  protocol + "://" + host + slice_url(slice_name,*args)
end

#access_deniedObject



149
150
151
152
153
154
155
156
157
# File 'app/controllers/application.rb', line 149

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

#authorized_nodeObject



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'app/controllers/application.rb', line 104

def authorized_node
#  if session[:level] == :admin
#    Chef::Log.debug("Authorized as Administrator")
#    true
#  elsif session[:level] == :node
#    Chef::Log.debug("Authorized as node")
#    if session[:node_name] == params[:id].gsub(/\./, '_')
#      true
#    else
#      raise(
#        Unauthorized,
#        "You are not the correct node for this action: #{session[:node_name]} instead of #{params[:id]}"
#      )
#    end
#  else
#    Chef::Log.debug("Unauthorized")
#    raise Unauthorized, "You are not allowed to take this action."
#  end
end

#authorized_userObject



124
125
126
127
128
129
130
131
132
# File 'app/controllers/application.rb', line 124

def authorized_user
  if session[:level] == :admin
    Chef::Log.debug("Authorized as Administrator")
    true
  else
    Chef::Log.debug("Unauthorized")
    raise Unauthorized, "The current user is not an Administrator, you can only Show and Edit the user itself. To control other users, login as an Administrator."
  end 
end

#cleanup_sessionObject



69
70
71
# File 'app/controllers/application.rb', line 69

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

#convert_newline_to_br(string) ⇒ Object



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

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

#edit_adminObject

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



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

def edit_admin
  is_admin(params[:user_id]) ? (!is_last_admin) : true
end

#get_available_recipesObject

The following should no longer be necessary for the re-factored cookbooks replated webui controllers (which talks to the API) But I want to wait until further verified before removing the code. [nuo]

def specific_cookbooks(node_name, cl)

valid_cookbooks = Hash.new
begin
  node = Chef::Node.load(node_name)
  recipes, default_attrs, override_attrs = node.run_list.expand
rescue Net::HTTPServerException
  recipes = []
end
recipes.each do |recipe|
  valid_cookbooks = expand_cookbook_deps(valid_cookbooks, cl, recipe)
end
valid_cookbooks

end

def expand_cookbook_deps(valid_cookbooks, cl, recipe)

cookbook = recipe
if recipe =~ /^(.+)::/
  cookbook = $1
end
Chef::Log.debug("Node requires #{cookbook}")
valid_cookbooks[cookbook] = true 
cl.[cookbook.to_sym].dependencies.each do |dep, versions|
  expand_cookbook_deps(valid_cookbooks, cl, dep) unless valid_cookbooks[dep]
end
valid_cookbooks

end

def load_all_files(segment, node_name=nil)

r = Chef::REST.new(Chef::Config[:chef_server_url])
cookbooks = r.get_rest("cookbooks")

files = Array.new
valid_cookbooks = node_name ? specific_cookbooks(node_name, cookbooks) : {} 
cl.each do |cookbook|
  if node_name
    next unless valid_cookbooks[cookbook.name.to_s]
  end
  segment_files(segment, cookbook).each do |sf|
    mo = sf.match("cookbooks/#{cookbook.name}/#{segment}/(.+)")
    file_name = mo[1]
    files << { 
      :cookbook => cookbook.name, 
      :name => file_name,
      :checksum => checksum(sf)
    }
  end
end
files

end



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'app/controllers/application.rb', line 258

def get_available_recipes
  r = Chef::REST.new(Chef::Config[:chef_server_url])
  result = Array.new
  cookbooks = r.get_rest("cookbooks")
  cookbooks.keys.sort.each do |key|
    cb = r.get_rest(cookbooks[key])
    cb["recipes"].each do |recipe|
      recipe["name"] =~ /(.+)\.rb/
      r_name = $1;
      if r_name == "default" 
        result << key
      else
        result << "#{key}::#{r_name}"
      end
    end
  end
  result
end

#is_admin(name) ⇒ Object



80
81
82
83
# File 'app/controllers/application.rb', line 80

def is_admin(name)
  user = Chef::WebUIUser.load(name)
  return user.admin
end

#is_last_adminObject

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



86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/controllers/application.rb', line 86

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

#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)


169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'app/controllers/application.rb', line 169

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

#login_requiredObject

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



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'app/controllers/application.rb', line 54

def 
 if session[:user]
   begin
     Chef::WebUIUser.load(session[:user]) rescue (raise NotFound, "Cannot find User #{session[:user]}, maybe it got deleted by an Administrator.")
   rescue   
     
   else 
     return session[:user]
   end 
 else  
   self.store_location
   throw(:halt, :access_denied)
 end
end

#logout_and_redirect_to_loginObject



73
74
75
76
77
# File 'app/controllers/application.rb', line 73

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

#redirect_back_or_default(default) ⇒ Object

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



143
144
145
146
147
# File 'app/controllers/application.rb', line 143

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

#segment_files(segment, cookbook) ⇒ Object



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'app/controllers/application.rb', line 187

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

#store_locationObject

Store the URI of the current request in the session.

We can return to this location by calling #redirect_back_or_default.



137
138
139
# File 'app/controllers/application.rb', line 137

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