diff options
author | Adam Jacob <adam@hjksolutions.com> | 2008-06-15 19:12:57 -0700 |
---|---|---|
committer | Adam Jacob <adam@hjksolutions.com> | 2008-06-15 19:12:57 -0700 |
commit | ebc1b392fe7e8f0fbabc305c299b4d365d2b4d9b (patch) | |
tree | 1d8882eee26e9ca7f039366c77973d79af1affb3 | |
parent | 14ca7fdc284eeaac9c66abd5878d7b24bd439180 (diff) | |
download | chef-ebc1b392fe7e8f0fbabc305c299b4d365d2b4d9b.tar.gz |
Moving chef-server into lib, reworking specs, adding storieschef-server-package
50 files changed, 2366 insertions, 18 deletions
diff --git a/config/chef-server.rb b/config/chef-server.rb new file mode 100644 index 0000000000..c773dcf1b9 --- /dev/null +++ b/config/chef-server.rb @@ -0,0 +1,11 @@ +# +# Example Chef Server Config + +cookbook_path File.join(File.dirname(__FILE__), "..", "examples", "config", "cookbooks") +node_path File.join(File.dirname(__FILE__), "..", "examples", "config", "nodes") +file_store_path File.join(File.dirname(__FILE__), "..", "examples", "store") +log_level :debug + +openid_providers [ "localhost:4001", "openid.hjksolutions.com" ] + +Chef::Log::Formatter.show_time = false diff --git a/examples/config/cookbooks/fakefile/recipes/default.rb b/examples/config/cookbooks/fakefile/recipes/default.rb index 7c79033d52..927a3e1f11 100644 --- a/examples/config/cookbooks/fakefile/recipes/default.rb +++ b/examples/config/cookbooks/fakefile/recipes/default.rb @@ -16,4 +16,5 @@ end mode 0644 action :create end -end
\ No newline at end of file +end + diff --git a/lib/chef.rb b/lib/chef.rb index 18e34e0ffb..4b132e6189 100644 --- a/lib/chef.rb +++ b/lib/chef.rb @@ -19,7 +19,11 @@ require 'rubygems' -Dir[File.join(File.dirname(__FILE__), 'chef/**/*.rb')].sort.each { |lib| require lib unless lib =~ /server/ } +Dir[ + File.join( + File.dirname(__FILE__), + 'chef/**/*.rb' + )].sort.each { |lib| require lib unless lib =~ /server/ } class Chef VERSION = '0.0.1' diff --git a/lib/chef/client.rb b/lib/chef/client.rb index 2cd11bb2e0..0ae7ef70e6 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -26,7 +26,7 @@ require 'facter' class Chef class Client - attr_accessor :node, :registration + attr_accessor :node, :registration, :safe_name def initialize() @node = nil @@ -43,8 +43,8 @@ class Chef converge end - def build_node - node_name = Facter["fqdn"].value ? Facter["fqdn"].value : Facter["hostname"].value + def build_node(node_name=nil) + node_name ||= Facter["fqdn"].value ? Facter["fqdn"].value : Facter["hostname"].value @safe_name = node_name.gsub(/\./, '_') begin @node = @rest.get_rest("nodes/#{@safe_name}") diff --git a/lib/chef/config.rb b/lib/chef/config.rb index 192b510d17..50524fd58b 100644 --- a/lib/chef/config.rb +++ b/lib/chef/config.rb @@ -49,6 +49,7 @@ class Chef :couchdb_url => "http://localhost:5984", :registration_url => "http://localhost:4000", :openid_url => "http://localhost:4001", + :couchdb_database => "chef", } class << self diff --git a/lib/chef/cookbook.rb b/lib/chef/cookbook.rb index ed9b75a1d9..75ab8f4ad6 100644 --- a/lib/chef/cookbook.rb +++ b/lib/chef/cookbook.rb @@ -92,7 +92,7 @@ class Chef def load_recipe(name, node, collection=nil, definitions=nil, cookbook_loader=nil) cookbook_name = @name recipe_name = nil - nmatch = name.match(/^(.+)::(.+)$/) + nmatch = name.match(/^(.+?)::(.+)$/) recipe_name = nmatch ? nmatch[2] : name unless @recipe_names.has_key?(recipe_name) diff --git a/lib/chef/couchdb.rb b/lib/chef/couchdb.rb index c5605080a6..83bf3982f7 100644 --- a/lib/chef/couchdb.rb +++ b/lib/chef/couchdb.rb @@ -13,16 +13,16 @@ class Chef def create_db @database_list = @rest.get_rest("_all_dbs") - unless @database_list.detect { |db| db == "chef" } - response = @rest.put_rest("chef", Hash.new) + unless @database_list.detect { |db| db == Chef::Config[:couchdb_database] } + response = @rest.put_rest(Chef::Config[:couchdb_database], Hash.new) end - "chef" + Chef::Config[:couchdb_database] end def create_design_document(name, data) to_update = true begin - old_doc = @rest.get_rest("chef/_design%2F#{name}") + old_doc = @rest.get_rest("#{Chef::Config[:couchdb_database]}/_design%2F#{name}") if data["version"] != old_doc["version"] data["_rev"] = old_doc["_rev"] Chef::Log.debug("Updating #{name} views") @@ -33,7 +33,7 @@ class Chef Chef::Log.debug("Creating #{name} views for the first time") end if to_update - @rest.put_rest("chef/_design%2F#{name}", data) + @rest.put_rest("#{Chef::Config[:couchdb_database]}/_design%2F#{name}", data) end true end @@ -49,7 +49,7 @@ class Chef :object => { :respond_to => :to_json }, } ) - @rest.put_rest("chef/#{obj_type}_#{safe_name(name)}", object) + @rest.put_rest("#{Chef::Config[:couchdb_database]}/#{obj_type}_#{safe_name(name)}", object) end def load(obj_type, name) @@ -63,7 +63,7 @@ class Chef :name => { :kind_of => String }, } ) - @rest.get_rest("chef/#{obj_type}_#{safe_name(name)}") + @rest.get_rest("#{Chef::Config[:couchdb_database]}/#{obj_type}_#{safe_name(name)}") end def delete(obj_type, name, rev=nil) @@ -78,14 +78,14 @@ class Chef } ) unless rev - last_obj = @rest.get_rest("chef/#{obj_type}_#{safe_name(name)}") + last_obj = @rest.get_rest("#{Chef::Config[:couchdb_database]}/#{obj_type}_#{safe_name(name)}") if last_obj.respond_to?(:couchdb_rev) rev = last_obj.couchdb_rev else rev = last_obj['_rev'] end end - @rest.delete_rest("chef/#{obj_type}_#{safe_name(name)}?rev=#{rev}") + @rest.delete_rest("#{Chef::Config[:couchdb_database]}/#{obj_type}_#{safe_name(name)}?rev=#{rev}") end def list(view, inflate=false) @@ -98,9 +98,9 @@ class Chef } ) if inflate - @rest.get_rest("chef/_view/#{view}/all") + @rest.get_rest("#{Chef::Config[:couchdb_database]}/_view/#{view}/all") else - @rest.get_rest("chef/_view/#{view}/all_id") + @rest.get_rest("#{Chef::Config[:couchdb_database]}/_view/#{view}/all_id") end end @@ -116,7 +116,7 @@ class Chef } ) begin - @rest.get_rest("chef/#{obj_type}_#{safe_name(name)}") + @rest.get_rest("#{Chef::Config[:couchdb_database]}/#{obj_type}_#{safe_name(name)}") true rescue false diff --git a/lib/chef_server/controllers/application.rb b/lib/chef_server/controllers/application.rb new file mode 100644 index 0000000000..4a0d247306 --- /dev/null +++ b/lib/chef_server/controllers/application.rb @@ -0,0 +1,69 @@ +class Application < Merb::Controller + + def fix_up_node_id + if params.has_key?(:id) + params[:id].gsub!(/_/, '.') + end + end + + def escape_node_id + if params.has_key?(:id) + params[:id].gsub(/_/, '.') + end + end + + def login_required + if session[:openid] + return session[:openid] + else + self.store_location + throw(:halt, :access_denied) + end + end + + 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 + + # Store the URI of the current request in the session. + # + # We can return to this location by calling #redirect_back_or_default. + def store_location + session[:return_to] = request.uri + end + + # Redirect to the URI stored by the most recent store_location call or + # to the passed default. + def redirect_back_or_default(default) + loc = session[:return_to] || default + session[:return_to] = nil + redirect loc + end + + def access_denied + case content_type + when :html + store_location + redirect url(:openid_consumer) + else + raise Unauthorized, "You must authenticate first!" + end + end + +end
\ No newline at end of file diff --git a/lib/chef_server/controllers/exceptions.rb b/lib/chef_server/controllers/exceptions.rb new file mode 100644 index 0000000000..7f72e57ad2 --- /dev/null +++ b/lib/chef_server/controllers/exceptions.rb @@ -0,0 +1,20 @@ +class Exceptions < Application + + provides :html, :json + + # handle NotFound exceptions (404) + def not_found + display params + end + + # handle NotAcceptable exceptions (406) + def not_acceptable + display params + end + + # handle BadRequest exceptions (400) + def bad_request + display params + end + +end
\ No newline at end of file diff --git a/lib/chef_server/controllers/nodes.rb b/lib/chef_server/controllers/nodes.rb new file mode 100644 index 0000000000..aa7273c47d --- /dev/null +++ b/lib/chef_server/controllers/nodes.rb @@ -0,0 +1,74 @@ +class Nodes < Application + + provides :html, :json + + before :fix_up_node_id + before :login_required, :only => [ :create, :update, :destroy ] + before :authorized_node, :only => [ :update, :destroy ] + + def index + @node_list = Chef::Node.list + display @node_list + end + + def show + begin + @node = Chef::Node.load(params[:id]) + rescue Net::HTTPServerException => e + raise NotFound, "Cannot load node #{params[:id]}" + end + display @node + end + + def create + @node = params.has_key?("inflated_object") ? params["inflated_object"] : nil + if @node + @status = 202 + @node.save + display @node + else + raise BadRequest, "You must provide a Node to create" + end + end + + def update + @node = params.has_key?("inflated_object") ? params["inflated_object"] : nil + if @node + @status = 202 + @node.save + display @node + else + raise NotFound, "You must provide a Node to update" + end + end + + def destroy + begin + @node = Chef::Node.load(params[:id]) + rescue RuntimeError => e + raise BadRequest, "Node #{params[:id]} does not exist to destroy!" + end + @status = 202 + @node.destroy + if content_type == :html + redirect url(:nodes) + else + display @node + end + end + + def compile + # Grab a Chef::Compile object + compile = Chef::Compile.new() + compile.load_node(params[:id]) + compile.node.save + compile.load_definitions + compile.load_recipes + @output = { + :node => compile.node, + :collection => compile.collection, + } + display @output + end + +end diff --git a/lib/chef_server/controllers/openid_consumer.rb b/lib/chef_server/controllers/openid_consumer.rb new file mode 100644 index 0000000000..1c8b76296c --- /dev/null +++ b/lib/chef_server/controllers/openid_consumer.rb @@ -0,0 +1,99 @@ +require 'pathname' + +require "openid" +require 'openid/store/filesystem' + +class OpenidConsumer < Application + + provides :html, :json + + def index + render + end + + def start + check_valid_openid_provider(params[:openid_identifier]) + begin + oidreq = consumer.begin(params[:openid_identifier]) + rescue OpenID::OpenIDError => e + raise BadRequest, "Discovery failed for #{params[:openid_identifier]}: #{e}" + end + return_to = absolute_url(:openid_consumer_complete) + realm = absolute_url(:openid_consumer) + + if oidreq.send_redirect?(realm, return_to, params[:immediate]) + return redirect(oidreq.redirect_url(realm, return_to, params[:immediate])) + else + @form_text = oidreq.form_markup(realm, return_to, params[:immediate], {'id' => 'openid_form'}) + render + end + end + + def complete + # FIXME - url_for some action is not necessarily the current URL. + current_url = absolute_url(:openid_consumer_complete) + parameters = params.reject{|k,v| k == "controller" || k == "action"} + oidresp = consumer.complete(parameters, current_url) + case oidresp.status + when OpenID::Consumer::FAILURE + if oidresp.display_identifier + raise BadRequest, "Verification of #{oidresp.display_identifier} failed: #{oidresp.message}" + else + raise BadRequest, "Verification failed: #{oidresp.message}" + end + when OpenID::Consumer::SUCCESS + session[:openid] = oidresp.identity_url + if oidresp.display_identifier =~ /openid\/server\/node\/(.+)$/ + session[:level] = :node + session[:node_name] = $1 + else + session[:level] = :admin + end + redirect_back_or_default(absolute_url(:nodes)) + return "Verification of #{oidresp.display_identifier} succeeded." + when OpenID::Consumer::SETUP_NEEDED + return "Immediate request failed - Setup Needed" + when OpenID::Consumer::CANCEL + return "OpenID transaction cancelled." + else + end + redirect absolute_url(:openid_consumer) + end + + def logout + session[:openid] = nil if session.has_key?(:openid) + session[:level] = nil if session.has_key?(:level) + session[:node_name] = nil if session.has_key?(:node_name) + redirect url(:top) + end + + private + + # Returns true if the openid is at a valid provider, based on whether :openid_providers is + # defined. Raises an exception if it is not an allowed provider. + def check_valid_openid_provider(openid) + if Chef::Config[:openid_providers] + fp = Chef::Config[:openid_providers].detect do |p| + case openid + when /^http:\/\/#{p}/, /^#{p}/ + true + else + false + end + end + unless fp + raise Unauthorized, "Sorry, #{openid} is not an allowed OpenID Provider." + end + end + true + end + + def consumer + if @consumer.nil? + dir = Pathname.new(Merb.root).join('db').join('cstore') + store = OpenID::Store::Filesystem.new(dir) + @consumer = OpenID::Consumer.new(session, store) + end + return @consumer + end +end diff --git a/lib/chef_server/controllers/openid_register.rb b/lib/chef_server/controllers/openid_register.rb new file mode 100644 index 0000000000..a6c30c95c5 --- /dev/null +++ b/lib/chef_server/controllers/openid_register.rb @@ -0,0 +1,74 @@ +# Controller for handling the login, logout process for "users" of our +# little server. Users have no password. This is just an example. + +require 'openid' + +class OpenidRegister < Application + + provides :html, :json + + before :fix_up_node_id + + def index + @headers['X-XRDS-Location'] = absolute_url(:controller => "openid_server", :action => "idp_xrds") + @registered_nodes = Chef::OpenIDRegistration.list(true) + Chef::Log.debug(@registered_nodes.inspect) + display @registered_nodes + end + + def show + begin + @registered_node = Chef::OpenIDRegistration.load(params[:id]) + rescue Net::HTTPServerException => e + if e.message =~ /^404/ + raise NotFound, "Cannot load node registration for #{params[:id]}" + else + raise e + end + end + Merb.logger.debug(@registered_node.inspect) + display @registered_node + end + + def create + params.has_key?(:id) or raise BadRequest, "You must provide an id to register" + params.has_key?(:password) or raise BadRequest, "You must provide a password to register" + if Chef::OpenIDRegistration.has_key?(params[:id]) + raise BadRequest, "You cannot re-register #{params[:id]}!" + end + @registered_node = Chef::OpenIDRegistration.new + @registered_node.name = params[:id] + @registered_node.set_password(params[:password]) + @registered_node.save + display @registered_node + end + + def update + raise BadRequest, "You cannot update your registration -- delete #{params[:id]} and re-register" + end + + def destroy + begin + r = Chef::OpenIDRegistration.load(params[:id]) + rescue Exception => e + raise BadRequest, "Cannot find the registration for #{params[:id]}" + end + r.destroy + if content_type == :html + redirect url(:registrations) + else + display({ :message => "Deleted registration for #{params[:id]}"}) + end + end + + def validate + begin + r = Chef::OpenIDRegistration.load(params[:id]) + rescue Exception => e + raise BadRequest, "Cannot find the registration for #{params[:id]}" + end + r.validated = r.validated ? false : true + r.save + redirect url(:registrations) + end +end diff --git a/lib/chef_server/controllers/openid_server.rb b/lib/chef_server/controllers/openid_server.rb new file mode 100644 index 0000000000..665af1fb6d --- /dev/null +++ b/lib/chef_server/controllers/openid_server.rb @@ -0,0 +1,218 @@ +require 'pathname' + +# load the openid library, first trying rubygems +#begin +# require "rubygems" +# require_gem "ruby-openid", ">= 1.0" +#rescue LoadError +require "openid" +require "openid/consumer/discovery" +require 'openid/store/filesystem' +require 'json' +#end + +class OpenidServer < Application + + provides :html, :json + + include Merb::OpenidServerHelper + include OpenID::Server + + layout nil + + before :fix_up_node_id + + def index + + oidreq = server.decode_request(params.reject{|k,v| k == "controller" || k == "action"}) + + # no openid.mode was given + unless oidreq + return "This is the Chef OpenID server endpoint." + end + + oidresp = nil + + if oidreq.kind_of?(CheckIDRequest) + identity = oidreq.identity + + if oidresp + nil + elsif self.is_authorized(identity, oidreq.trust_root) + oidresp = oidreq.answer(true, nil, identity) + elsif oidreq.immediate + server_url = url :openid_server + oidresp = oidreq.answer(false, server_url) + else + if content_type != 'application/json' + session[:last_oidreq] = oidreq + response = { :action => url(:openid_server_decision) } + return response.to_json + else + return show_decision_page(oidreq) + end + end + else + oidresp = server.handle_request(oidreq) + end + + self.render_response(oidresp) + end + + def show_decision_page(oidreq, message="Do you trust this site with your identity?") + session[:last_oidreq] = oidreq + @oidreq = oidreq + + if message + session[:notice] = message + end + + render :template => 'openid_server/decide' + end + + def node_page + unless Chef::OpenIDRegistration.has_key?(params[:id]) + raise NotFound, "Cannot find registration for #{params[:id]}" + end + + # Yadis content-negotiation: we want to return the xrds if asked for. + accept = request.env['HTTP_ACCEPT'] + + # This is not technically correct, and should eventually be updated + # to do real Accept header parsing and logic. Though I expect it will work + # 99% of the time. + if accept and accept.include?('application/xrds+xml') + return node_xrds + end + + # content negotiation failed, so just render the user page + xrds_url = absolute_url(:openid_node_xrds, :id => params[:id]) + identity_page = <<EOS +<html><head> +<meta http-equiv="X-XRDS-Location" content="#{xrds_url}" /> +<link rel="openid.server" href="#{absolute_url(:openid_node, :id => params[:id])}" /> +</head><body><p>OpenID identity page for registration #{params[:id]}</p> +</body></html> +EOS + + # Also add the Yadis location header, so that they don't have + # to parse the html unless absolutely necessary. + @headers['X-XRDS-Location'] = xrds_url + render identity_page + end + + def node_xrds + types = [ + OpenID::OPENID_2_0_TYPE, + OpenID::OPENID_1_0_TYPE + ] + + render_xrds(types) + end + + def idp_xrds + types = [ + OpenID::OPENID_IDP_2_0_TYPE, + ] + + render_xrds(types) + end + + def decision + oidreq = session[:last_oidreq] + session[:last_oidreq] = nil + + if params.has_key?(:cancel) + Merb.logger.info("Cancelling OpenID Authentication") + return(redirect(oidreq.cancel_url)) + else + identity = oidreq.identity + identity =~ /node\/(.+)$/ + openid_node = Chef::OpenIDRegistration.load($1) + unless openid_node.validated + raise Unauthorized, "This nodes registration has not been validated" + end + if openid_node.password == encrypt_password(openid_node.salt, params[:password]) + if session[:approvals] + session[:approvals] << oidreq.trust_root + else + session[:approvals] = [oidreq.trust_root] + end + oidresp = oidreq.answer(true, nil, identity) + return self.render_response(oidresp) + else + raise Unauthorized, "Invalid credentials" + end + end + end + + protected + + def encrypt_password(salt, password) + Digest::SHA1.hexdigest("--#{salt}--#{password}--") + end + + def server + if @server.nil? + server_url = absolute_url(:openid_server) + dir = Pathname.new(Merb.root).join('db').join('openid-store') + store = OpenID::Store::Filesystem.new(dir) + @server = Server.new(store, server_url) + end + return @server + end + + def approved(trust_root) + return false if session[:approvals].nil? + return session[:approvals].member?(trust_root) + end + + def is_authorized(identity_url, trust_root) + return (session[:username] and (identity_url == url_for_user) and self.approved(trust_root)) + end + + def render_xrds(types) + type_str = "" + + types.each { |uri| + type_str += "<Type>#{uri}</Type>\n " + } + + yadis = <<EOS +<?xml version="1.0" encoding="UTF-8"?> +<xrds:XRDS + xmlns:xrds="xri://$xrds" + xmlns="xri://$xrd*($v*2.0)"> + <XRD> + <Service priority="0"> + #{type_str} + <URI>#{absolute_url(:openid_server)}</URI> + </Service> + </XRD> +</xrds:XRDS> +EOS + + @headers['content-type'] = 'application/xrds+xml' + render yadis + end + + def render_response(oidresp) + if oidresp.needs_signing + signed_response = server.signatory.sign(oidresp) + end + web_response = server.encode_response(oidresp) + + case web_response.code + when HTTP_OK + @status = 200 + render web_response.body + when HTTP_REDIRECT + redirect web_response.headers['location'] + else + @status = 400 + render web_response.body + end + end + + +end diff --git a/lib/chef_server/helpers/global_helpers.rb b/lib/chef_server/helpers/global_helpers.rb new file mode 100644 index 0000000000..1ef7ac9331 --- /dev/null +++ b/lib/chef_server/helpers/global_helpers.rb @@ -0,0 +1,17 @@ +module Merb + module GlobalHelpers + # helpers defined here available to all views. + def resource_collection(collection) + html = "<ul>" + collection.each do |resource| + html << "<li><b>#{resource.class}</b></li>" + end + html << "</ul>" + html + end + + def node_escape(node) + node.gsub(/\./, '_') + end + end +end diff --git a/lib/chef_server/helpers/nodes_helper.rb b/lib/chef_server/helpers/nodes_helper.rb new file mode 100644 index 0000000000..5e6c25c453 --- /dev/null +++ b/lib/chef_server/helpers/nodes_helper.rb @@ -0,0 +1,19 @@ +module Merb + module NodesHelper + def recipe_list(node) + response = "" + node.recipes.each do |recipe| + response << "<li>#{recipe}</li>" + end + response + end + + def attribute_list(node) + response = "" + node.each_attribute do |k,v| + response << "<li><b>#{k}</b>: #{v}</li>" + end + response + end + end +end
\ No newline at end of file diff --git a/lib/chef_server/helpers/openid_server_helpers.rb b/lib/chef_server/helpers/openid_server_helpers.rb new file mode 100644 index 0000000000..73be9cab27 --- /dev/null +++ b/lib/chef_server/helpers/openid_server_helpers.rb @@ -0,0 +1,9 @@ +module Merb + module OpenidServerHelper + + def url_for_user + url(:openid_node, :username => session[:username]) + end + + end +end diff --git a/lib/chef_server/init.rb b/lib/chef_server/init.rb new file mode 100644 index 0000000000..14029c1295 --- /dev/null +++ b/lib/chef_server/init.rb @@ -0,0 +1,165 @@ +Merb.root = File.join(File.dirname(__FILE__)) + +# +# ==== Structure of Merb initializer +# +# 1. Load paths. +# 2. Dependencies configuration. +# 3. Libraries (ORM, testing tool, etc) you use. +# 4. Application-specific configuration. + +# +# ==== Set up load paths +# + +# Make the app's "gems" directory a place where gems are loaded from. +# Note that gems directory must have a structure RubyGems uses for +# directories under which gems are kept. +# +# To conveniently set it up use gem install -i <merb_app_root/gems> +# when installing gems. This will set up the structure under /gems +# automagically. +# +# An example: +# +# You want to bundle ActiveRecord and ActiveSupport with your Merb +# application to be deployment environment independent. To do so, +# install gems into merb_app_root/gems directory like this: +# +# gem install -i ~/dev/merbapp/gems activesupport-post-2.0.2gem activerecord-post-2.0.2.gem +# +# Since RubyGems will search merb_app_root/gems for dependencies, order +# in statement above is important: we need to install ActiveSupport which +# ActiveRecord depends on first. +# +# Remember that bundling of dependencies as gems with your application +# makes it independent of the environment it runs in and is a very +# good, encouraged practice to follow. +Gem.clear_paths +Gem.path.unshift(Merb.root / "gems") + +# If you want modules and classes from libraries organized like +# merbapp/lib/magicwand/lib/magicwand.rb to autoload, +# uncomment this. + + +# Merb.push_path(:lib, Merb.root / "lib") # uses **/*.rb as path glob. + +# ==== Dependencies + +# These are some examples of how you might specify dependencies. +# Dependencies load is delayed to one of later Merb app +# boot stages. It may be important when +# later part of your configuration relies on libraries specified +# here. +# +# dependencies "RedCloth", "merb_helpers" +# OR +# dependency "RedCloth", "> 3.0" +# OR +# dependencies "RedCloth" => "> 3.0", "ruby-aes-cext" => "= 1.0" +Merb::BootLoader.after_app_loads do + # Add dependencies here that must load after the application loads: + Chef::Config.from_file(File.join(File.dirname(__FILE__), "..", "..", "config", "chef-server.rb")) + Chef::Queue.connect + + # dependency "magic_admin" # this gem uses the app's model classes +end + +# +# ==== Set up your ORM of choice +# + +# Merb doesn't come with database support by default. You need +# an ORM plugin. Install one, and uncomment one of the following lines, +# if you need a database. + +# Uncomment for DataMapper ORM +# use_orm :datamapper + +# Uncomment for ActiveRecord ORM +# use_orm :activerecord + +# Uncomment for Sequel ORM +# use_orm :sequel + +Merb.push_path(:lib, File.join(File.dirname(__FILE__), "..", "chef")) +Merb.push_path(:controller, File.join(File.dirname(__FILE__), "controllers")) +Merb.push_path(:model, File.join(File.dirname(__FILE__), "models")) +Merb.push_path(:view, File.join(File.dirname(__FILE__), "views")) +Merb.push_path(:helper, File.join(File.dirname(__FILE__), "helpers")) +Merb.push_path(:public, Merb.root_path("public"), nil) + +require 'merb-haml' + + +# +# ==== Pick what you test with +# + +# This defines which test framework the generators will use +# rspec is turned on by default +# +# Note that you need to install the merb_rspec if you want to ue +# rspec and merb_test_unit if you want to use test_unit. +# merb_rspec is installed by default if you did gem install +# merb. +# +# use_test :test_unit +use_test :rspec + + +# +# ==== Set up your basic configuration +# +Merb::Config.use do |c| + # Sets up a custom session id key, if you want to piggyback sessions of other applications + # with the cookie session store. If not specified, defaults to '_session_id'. + c[:session_id_key] = '_chef_server_session_id' + c[:session_secret_key] = '0992ea491c30ec76c98367c1ca53b18c1e7c5b30' + c[:session_store] = 'cookie' + c[:exception_details] = true + c[:reload_classes] = true + c[:log_level] = :debug + c[:log_file] = Merb.log_path + "/chef-server.log" +end + +Merb.logger.info("Compiling routes...") +Merb::Router.prepare do |r| + # RESTful routes + # r.resources :posts + + # This is the default route for /:controller/:action/:id + # This is fine for most cases. If you're heavily using resource-based + # routes, you may want to comment/remove this line to prevent + # clients from calling your create or destroy actions with a GET + + r.resources :nodes + r.resources :nodes, :member => { :compile => :get } + + #r.resources :openid do |res| + # res.resources :register, :controller => "openid_register" + # res.resources :server, :controller => "openid_server" + #end + + r.resources :registrations, :controller => "openid_register" + r.resources :registrations, :controller => "openid_register", :member => { :validate => :post } + r.match("/openid/server").to(:controller => "openid_server", :action => "index").name(:openid_server) + r.match("/openid/server/server/xrds"). + to(:controller => "openid_server", :action => 'idp_xrds').name(:openid_server_xrds) + r.match("/openid/server/node/:id"). + to(:controller => "openid_server", :action => 'node_page').name(:openid_node) + r.match('/openid/server/node/:id/xrds'). + to(:controller => 'openid_server', :action => 'node_xrds').name(:openid_node_xrds) + r.match('/openid/server/decision').to(:controller => "openid_server", :action => "decision").name(:openid_server_decision) + r.match('/openid/consumer').to(:controller => 'openid_consumer', :action => 'index').name(:openid_consumer) + r.match('/openid/consumer/start').to(:controller => 'openid_consumer', :action => 'start').name(:openid_consumer_start) + r.match('/openid/consumer/complete').to(:controller => 'openid_consumer', :action => 'complete').name(:openid_consumer_complete) + r.match('/openid/consumer/logout').to(:controller => 'openid_consumer', :action => 'logout').name(:openid_consumer_logout) + + #r.default_routes + + # Change this for your home page to be available at / + r.match('/').to(:controller => 'nodes', :action =>'index').name(:top) +end + diff --git a/lib/chef_server/log/chef-server.log b/lib/chef_server/log/chef-server.log new file mode 100644 index 0000000000..bfb7e4e771 --- /dev/null +++ b/lib/chef_server/log/chef-server.log @@ -0,0 +1,434 @@ +Mon, 16 Jun 2008 01:37:16 GMT ~ info ~ Logfile created + ~ Using 'share-nothing' cookie sessions (4kb limit per client) + ~ Using Mongrel adapter + ~ Request: + ~ Routed to: {:controller=>"nodes", :action=>"index"} + ~ Controller 'Nodes' not found - (Merb::ControllerExceptions::NotFound) +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:50:in `handle' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/application.rb:53:in `call' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/handler/mongrel.rb:72:in `process' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:159:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `each' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `run' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/adapter/mongrel.rb:22:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/server.rb:44:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core.rb:36:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/bin/merb:12 +/usr/bin/merb:19:in `load' +/usr/bin/merb:19 + ~ + + ~ Request: + ~ Routed to: {:controller=>"nodes", :action=>"index"} + ~ Controller 'Nodes' not found - (Merb::ControllerExceptions::NotFound) +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:50:in `handle' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/application.rb:53:in `call' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/handler/mongrel.rb:72:in `process' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:159:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `each' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `run' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/adapter/mongrel.rb:22:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/server.rb:44:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core.rb:36:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/bin/merb:12 +/usr/bin/merb:19:in `load' +/usr/bin/merb:19 + ~ + + ~ Using 'share-nothing' cookie sessions (4kb limit per client) + ~ Using Mongrel adapter + ~ Request: + ~ Routed to: {:controller=>"nodes", :action=>"index"} + ~ Params: {"action"=>"index", "controller"=>"nodes"} + ~ {:dispatch_time=>0.386588, :action_time=>0.386157, :before_filters_time=>0.000113, :after_filters_time=>9.0e-06} + ~ + + ~ Request: /stylesheets/master.css + ~ No routes match the request, /stylesheets/master.css - (Merb::ControllerExceptions::NotFound) +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:34:in `handle' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/application.rb:53:in `call' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/handler/mongrel.rb:72:in `process' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:159:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `each' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `run' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/adapter/mongrel.rb:22:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/server.rb:44:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core.rb:36:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/bin/merb:12 +/usr/bin/merb:19:in `load' +/usr/bin/merb:19 + ~ + + ~ Request: /nodes + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"nodes"} + ~ {:dispatch_time=>0.012587, :action_time=>0.012287, :before_filters_time=>4.0e-05, :after_filters_time=>7.0e-06} + ~ + + ~ Request: /stylesheets/master.css + ~ No routes match the request, /stylesheets/master.css - (Merb::ControllerExceptions::NotFound) +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:34:in `handle' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/application.rb:53:in `call' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/handler/mongrel.rb:72:in `process' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:159:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `each' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `run' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/adapter/mongrel.rb:22:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/server.rb:44:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core.rb:36:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/bin/merb:12 +/usr/bin/merb:19:in `load' +/usr/bin/merb:19 + ~ + + ~ Request: /registrations + ~ Routed to: {:controller=>"openid_register", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"openid_register"} + ~ {:dispatch_time=>0.064962, :action_time=>0.064639, :before_filters_time=>3.9e-05, :after_filters_time=>1.2e-05} + ~ + + ~ Request: /stylesheets/master.css + ~ No routes match the request, /stylesheets/master.css - (Merb::ControllerExceptions::NotFound) +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:34:in `handle' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/application.rb:53:in `call' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/handler/mongrel.rb:72:in `process' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:159:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `each' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `run' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/adapter/mongrel.rb:22:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/server.rb:44:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core.rb:36:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/bin/merb:12 +/usr/bin/merb:19:in `load' +/usr/bin/merb:19 + ~ + + ~ Request: /nodes + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"nodes"} + ~ {:dispatch_time=>0.011244, :action_time=>0.011029, :before_filters_time=>3.0e-05, :after_filters_time=>8.0e-06} + ~ + + ~ Request: /stylesheets/master.css + ~ No routes match the request, /stylesheets/master.css - (Merb::ControllerExceptions::NotFound) +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:34:in `handle' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/application.rb:53:in `call' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/handler/mongrel.rb:72:in `process' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:159:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `each' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `run' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/adapter/mongrel.rb:22:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/server.rb:44:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core.rb:36:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/bin/merb:12 +/usr/bin/merb:19:in `load' +/usr/bin/merb:19 + ~ + + ~ Request: /registrations + ~ Routed to: {:controller=>"openid_register", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"openid_register"} + ~ {:dispatch_time=>0.01562, :action_time=>0.015291, :before_filters_time=>4.1e-05, :after_filters_time=>8.0e-06} + ~ + + ~ Request: /stylesheets/master.css + ~ No routes match the request, /stylesheets/master.css - (Merb::ControllerExceptions::NotFound) +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:34:in `handle' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/application.rb:53:in `call' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/handler/mongrel.rb:72:in `process' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:159:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `each' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `run' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/adapter/mongrel.rb:22:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/server.rb:44:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core.rb:36:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/bin/merb:12 +/usr/bin/merb:19:in `load' +/usr/bin/merb:19 + ~ + + ~ Request: /nodes + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"nodes"} + ~ {:dispatch_time=>0.01432, :action_time=>0.014052, :before_filters_time=>5.5e-05, :after_filters_time=>8.0e-06} + ~ + + ~ Request: /stylesheets/master.css + ~ No routes match the request, /stylesheets/master.css - (Merb::ControllerExceptions::NotFound) +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:34:in `handle' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/application.rb:53:in `call' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/handler/mongrel.rb:72:in `process' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:159:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `each' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `run' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/adapter/mongrel.rb:22:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/server.rb:44:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core.rb:36:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/bin/merb:12 +/usr/bin/merb:19:in `load' +/usr/bin/merb:19 + ~ + + ~ Request: /registrations + ~ Routed to: {:controller=>"openid_register", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"openid_register"} + ~ {:dispatch_time=>0.014029, :action_time=>0.013795, :before_filters_time=>2.9e-05, :after_filters_time=>1.0e-05} + ~ + + ~ Request: /stylesheets/master.css + ~ No routes match the request, /stylesheets/master.css - (Merb::ControllerExceptions::NotFound) +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:34:in `handle' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/application.rb:53:in `call' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/handler/mongrel.rb:72:in `process' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:159:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `each' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `run' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/adapter/mongrel.rb:22:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/server.rb:44:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core.rb:36:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/bin/merb:12 +/usr/bin/merb:19:in `load' +/usr/bin/merb:19 + ~ + + ~ Request: /nodes + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"nodes"} + ~ {:dispatch_time=>0.012692, :action_time=>0.012386, :before_filters_time=>4.0e-05, :after_filters_time=>9.0e-06} + ~ + + ~ Request: /stylesheets/master.css + ~ No routes match the request, /stylesheets/master.css - (Merb::ControllerExceptions::NotFound) +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/dispatch/dispatcher.rb:34:in `handle' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/application.rb:53:in `call' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/handler/mongrel.rb:72:in `process' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:159:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `each' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:158:in `process_client' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:285:in `run' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `initialize' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `new' +/Library/Ruby/Gems/1.8/gems/mongrel-1.1.4/lib/mongrel.rb:268:in `run' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/rack/adapter/mongrel.rb:22:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core/server.rb:44:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/lib/merb-core.rb:36:in `start' +/Library/Ruby/Gems/1.8/gems/merb-core-0.9.3/bin/merb:12 +/usr/bin/merb:19:in `load' +/usr/bin/merb:19 + ~ + + ~ Using 'share-nothing' cookie sessions (4kb limit per client) + ~ Using Mongrel adapter + ~ Request: /nodes + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"nodes"} + ~ {:dispatch_time=>0.018469, :action_time=>0.018213, :before_filters_time=>3.1e-05, :after_filters_time=>1.2e-05} + ~ + + ~ Request: /stylesheets/master.css + ~ Request: /nodes + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"nodes"} + ~ {:dispatch_time=>0.013904, :action_time=>0.013629, :before_filters_time=>3.7e-05, :after_filters_time=>9.0e-06} + ~ + + ~ Request: /stylesheets/master.css + ~ Request: /registrations + ~ Routed to: {:controller=>"openid_register", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"openid_register"} + ~ {:dispatch_time=>0.019964, :action_time=>0.019629, :before_filters_time=>3.4e-05, :after_filters_time=>9.0e-06} + ~ + + ~ Request: /nodes + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"nodes"} + ~ {:dispatch_time=>0.014237, :action_time=>0.013883, :before_filters_time=>4.6e-05, :after_filters_time=>9.0e-06} + ~ + + ~ Request: /registrations + ~ Routed to: {:controller=>"openid_register", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"openid_register"} + ~ {:dispatch_time=>0.020176, :action_time=>0.019838, :before_filters_time=>3.5e-05, :after_filters_time=>1.2e-05} + ~ + + ~ Request: /nodes + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"nodes"} + ~ {:dispatch_time=>0.012408, :action_time=>0.012107, :before_filters_time=>4.5e-05, :after_filters_time=>7.0e-06} + ~ + + ~ Request: /nodes/adam + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"show", :id=>"adam"} + ~ Params: {"format"=>nil, "action"=>"show", "id"=>"adam", "controller"=>"nodes"} + ~ {:dispatch_time=>0.03838, :action_time=>0.038078, :before_filters_time=>4.8e-05, :after_filters_time=>1.2e-05} + ~ + + ~ Request: /stylesheets/master.css + ~ Request: /nodes/adam/compile + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"compile", :id=>"adam"} + ~ Params: {"format"=>nil, "action"=>"compile", "id"=>"adam", "controller"=>"nodes"} + ~ {:dispatch_time=>4.73037, :action_time=>4.730021, :before_filters_time=>5.0e-05, :after_filters_time=>1.7e-05} + ~ + + ~ Using 'share-nothing' cookie sessions (4kb limit per client) + ~ Using Mongrel adapter + ~ Request: /nodes/latte_local + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"show", :id=>"latte_local"} + ~ Params: {"format"=>nil, "action"=>"show", "id"=>"latte_local", "controller"=>"nodes"} + ~ {:dispatch_time=>0.00587, :action_time=>0.005648, :before_filters_time=>3.6e-05, :after_filters_time=>7.0e-06} + ~ + + ~ Request: /registrations/latte_local + ~ Routed to: {:controller=>"openid_register", :format=>nil, :action=>"show", :id=>"latte_local"} + ~ Params: {"format"=>nil, "action"=>"show", "id"=>"latte_local", "controller"=>"openid_register"} + ~ #<Chef::OpenIDRegistration:0x12c9420 @validated=true, @couchdb_rev="744961245", @password="31c954f5c3a7681dc17835e300c092519b6c2a09", @salt="Thu Jun 12 14:15:08 -0700 20088jr1S8ApvctBoObFIdkyHrxRB6t1XY", @name="latte_local", @couchdb=#<Chef::CouchDB:0x12c93f8 @rest=#<Chef::REST:0x12c93a8 @cookies={}, @url="http://localhost:5984">>> + ~ {:dispatch_time=>0.017782, :action_time=>0.017557, :before_filters_time=>3.1e-05, :after_filters_time=>1.3e-05} + ~ + + ~ Request: /openid/server/node/latte_local + ~ Routed to: {:controller=>"openid_server", :action=>"node_page", :id=>"latte_local"} + ~ Params: {"action"=>"node_page", "id"=>"latte_local", "controller"=>"openid_server"} + ~ {:dispatch_time=>0.004956, :action_time=>0.004722, :before_filters_time=>3.3e-05, :after_filters_time=>7.0e-06} + ~ + + ~ Request: /openid/server + ~ Routed to: {:controller=>"openid_server", :action=>"index"} + ~ Params: {"openid.session_type"=>"DH-SHA1", "openid.mode"=>"associate", "openid.assoc_type"=>"HMAC-SHA1", "openid.ns"=>"http://specs.openid.net/auth/2.0", "action"=>"index", "openid.dh_consumer_public"=>"Zn3+K7sQLiNqeA4bIeX0eX4zcyaNl0/Scyve/CwPUmX5ycjl9Sb5R1sVzw3x9NsKUIqSTKSD5kfmDNj15ECLWWIuv7m6cPGdhmEf1qZyvfZSEmYV5iEFbm5JopZNQE2FtSI3iQOw0AB00tZEpmDacp39qvv1H110uTs5u2r0SDY=", "controller"=>"openid_server"} + ~ {:dispatch_time=>0.104243, :action_time=>0.103829, :before_filters_time=>1.9e-05, :after_filters_time=>5.0e-06} + ~ + + ~ Request: /openid/consumer/start + ~ Routed to: {:controller=>"openid_consumer", :action=>"start"} + ~ Params: {"submit"=>"Verify", "action"=>"start", "controller"=>"openid_consumer", "openid_identifier"=>"http://localhost:4001/openid/server/node/latte_local"} + ~ Redirecting to: http://localhost:4001/openid/server?openid.assoc_handle=%7BHMAC-SHA1%7D%7B4855c779%7D%7BdTZXcQ%3D%3D%7D&openid.claimed_id=http%3A%2F%2Flocalhost%3A4001%2Fopenid%2Fserver%2Fnode%2Flatte_local&openid.identity=http%3A%2F%2Flocalhost%3A4001%2Fopenid%2Fserver%2Fnode%2Flatte_local&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.realm=http%3A%2F%2Flocalhost%3A4000%2Fopenid%2Fconsumer&openid.return_to=http%3A%2F%2Flocalhost%3A4000%2Fopenid%2Fconsumer%2Fcomplete + ~ {:dispatch_time=>0.270794, :action_time=>0.270403, :before_filters_time=>1.8e-05, :after_filters_time=>1.4e-05} + ~ + + ~ Request: /openid/server + ~ Routed to: {:controller=>"openid_server", :action=>"index"} + ~ Params: {"openid.claimed_id"=>"http://localhost:4001/openid/server/node/latte_local", "openid.mode"=>"checkid_setup", "openid.return_to"=>"http://localhost:4000/openid/consumer/complete", "openid.ns"=>"http://specs.openid.net/auth/2.0", "action"=>"index", "controller"=>"openid_server", "openid.identity"=>"http://localhost:4001/openid/server/node/latte_local", "openid.assoc_handle"=>"{HMAC-SHA1}{4855c779}{dTZXcQ==}", "openid.realm"=>"http://localhost:4000/openid/consumer"} + ~ {:dispatch_time=>0.002846, :action_time=>0.002304, :before_filters_time=>1.8e-05, :after_filters_time=>7.0e-06} + ~ + + ~ Request: /openid/server/decision + ~ Routed to: {:controller=>"openid_server", :action=>"decision"} + ~ Params: {"action"=>"decision", "controller"=>"openid_server", "password"=>"wCFIjJVHS7Nu2OGjW7SFn21HPSHRW1Ci8C6G4plq"} + ~ Redirecting to: http://localhost:4000/openid/consumer/complete?openid.assoc_handle=%7BHMAC-SHA1%7D%7B4855c779%7D%7BdTZXcQ%3D%3D%7D&openid.claimed_id=http%3A%2F%2Flocalhost%3A4001%2Fopenid%2Fserver%2Fnode%2Flatte_local&openid.identity=http%3A%2F%2Flocalhost%3A4001%2Fopenid%2Fserver%2Fnode%2Flatte_local&openid.mode=id_res&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.op_endpoint=http%3A%2F%2Flocalhost%3A4001%2Fopenid%2Fserver&openid.response_nonce=2008-06-16T01%3A52%3A57ZuyqSwR&openid.return_to=http%3A%2F%2Flocalhost%3A4000%2Fopenid%2Fconsumer%2Fcomplete&openid.sig=Zz9S7OR%2FAbC%2FzCHAgceVRSb00Iw%3D&openid.signed=assoc_handle%2Cclaimed_id%2Cidentity%2Cmode%2Cns%2Cop_endpoint%2Cresponse_nonce%2Creturn_to%2Csigned + ~ {:dispatch_time=>0.006955, :action_time=>0.006688, :before_filters_time=>2.1e-05, :after_filters_time=>8.0e-06} + ~ + + ~ Request: /openid/consumer/complete + ~ Routed to: {:controller=>"openid_consumer", :action=>"complete"} + ~ Params: {"openid.claimed_id"=>"http://localhost:4001/openid/server/node/latte_local", "openid.mode"=>"id_res", "openid.return_to"=>"http://localhost:4000/openid/consumer/complete", "openid.sig"=>"Zz9S7OR/AbC/zCHAgceVRSb00Iw=", "openid.ns"=>"http://specs.openid.net/auth/2.0", "openid.op_endpoint"=>"http://localhost:4001/openid/server", "action"=>"complete", "openid.response_nonce"=>"2008-06-16T01:52:57ZuyqSwR", "controller"=>"openid_consumer", "openid.identity"=>"http://localhost:4001/openid/server/node/latte_local", "openid.assoc_handle"=>"{HMAC-SHA1}{4855c779}{dTZXcQ==}", "openid.signed"=>"assoc_handle,claimed_id,identity,mode,ns,op_endpoint,response_nonce,return_to,signed"} + ~ Redirecting to: http://localhost:4000/nodes + ~ {:dispatch_time=>0.004359, :action_time=>0.003761, :before_filters_time=>9.0e-06, :after_filters_time=>6.0e-06} + ~ + + ~ Request: /nodes + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"index"} + ~ Params: {"format"=>nil, "action"=>"index", "controller"=>"nodes"} + ~ {:dispatch_time=>0.012424, :action_time=>0.012216, :before_filters_time=>2.7e-05, :after_filters_time=>1.2e-05} + ~ + + ~ Request: /nodes/latte_local + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"update", :id=>"latte_local"} + ~ Params: {"format"=>nil, "inflated_object"=>#<Chef::Node:0x1a007fc @couchdb_rev="3414278843", @recipe_list=["tempfile", "fakefile"], @attribute={"macosx_productname"=>"Mac OS X", "kernel"=>"Darwin", "sp_current_processor_speed"=>"2.4 GHz", "sp_smc_version"=>"1.27f1", "sp_serial_number"=>"W88153RWYJX", "hardwaremodel"=>"i386", "sp_boot_rom_version"=>"MBP41.00C1.B03", "operatingsystemrelease"=>"9.3.0", "sp_os_version"=>"Mac OS X 10.5.3 (9D34)", "ipaddress"=>"192.168.0.101", "sp_kernel_version"=>"Darwin 9.3.0", "jesse"=>"is neat", "kernelrelease"=>"9.3.0", "sp_boot_mode"=>"normal_boot", "ps"=>"ps -auxwww", "fqdn"=>"latte.local", "sp_uptime"=>"up 13:6:36:0", "macosx_productversion"=>"10.5.3", "sp_packages"=>1, "domain"=>"local", "sp_l2_cache"=>"3 MB", "macosx_buildversion"=>"9D34", "sp_boot_volume"=>"Macintosh HD", "sp_local_host_name"=>"latte", "sp_machine_name"=>"MacBookPro", "sp_bus_speed"=>"800 MHz", "sp_physical_memory"=>"4 GB", "sp_user_name"=>"Adam Jacob (adam)", "sshrsakey"=>"AAAAB3NzaC1yc2EAAAABIwAAAQEAr3ZIJusU+7/cbCyJ3hRp6MmqpmvTPl5beAuergDEcDnJ75xlt+/0V6C7kPmgNY2FMytO0wTj/myAd7Ylf2hVwMRq63Cdb/0LLAln0luiqfcLLQtZFJnhn4txV0RxtdNoaXj7rFohBHIxDJ9EAzWmNSm9tCQOY4ro65qsGLUU4YXfhcLJw4LSbsYJa8jVThb/tbcwZz6D+m4m2/lRvpXhY7cAj/dP12b3DY3v3tKl0GaELZtGuEt49S7SPPq05YfL6X1JfAd6l29FfkxGStMa/K8rg1Hmh0PJM5WQZcm+0tr9nllLLIMMf4rk2JznnFyB64NOMt97qIhtM1v7NP4pgw==", "owner"=>"Adam Jacob", "rubyversion"=>"1.8.6", "sp_cpu_type"=>"Intel Core 2 Duo", "sp_machine_model"=>"MacBookPro4,1", "sp_mmm_entry"=>{"MMM_state"=>"MMM_enabled"}, "hostname"=>"latte", "facterversion"=>"1.3.8", "operatingsystem"=>"Darwin", "macaddress"=>"00:1f:f3:4e:16:ab", "sshdsakey"=>"AAAAB3NzaC1kc3MAAACBAOzWvVwoQ0HQGtXq42x8L8Wn9rgjbVEAx3h3Uu9jMHA6ftZRiSJizgQlnoLjLkAiUARQUEho/TJWdCx/TQkWnIcrGjkPhGrovzq9212w5x8shYA3qPTppwtajenOEKJFjNSqW/i8dHkansUrGv5V49zc9KVfJ+SUkVP3CXAGndTHAAAAFQCG6h9qRnwjUhRYERqx+BJmOr3RCwAAAIByJIWvZ8qeK28S1b+ERfy0+1jVVYCqFkJfuKp3nQLi7bF21w/C0SVf9Nkpo0Ecw7hufGgyCo3XsxayedSrNQgy954aTiyqdCxakhwECIWBaNuWLTRb5oMcbzvkr/JLRNR8cOJrIb5d7KMAGrU29mZ/0smFptikGz2tc1scqP26aQAAAIEA2Gcgs3wsPa36a75qS7mkE8paDAEgiBAq64OUkkLSy6lmNNtGW0IApPYOC91S0L01aODhtJqB2txHOSP6GokxgrKTcoA5fGwYbxrGw7pddCDP+5AU8JghVIwF/Z9hGkhCk2ZQi8YUJW0lpJzEQqZmJ/XShaayeR2kbHOj4/g0BOQ=", "sp_number_processors"=>2}, @name="latte.local", @couchdb=#<Chef::CouchDB:0x1a00630 @rest=#<Chef::REST:0x1a005f4 @cookies={}, @url="http://localhost:5984">>>, "action"=>"update", "id"=>"latte_local", "controller"=>"nodes"} + ~ {:dispatch_time=>0.022162, :action_time=>0.021556, :before_filters_time=>0.000119, :after_filters_time=>8.0e-06} + ~ + + ~ Request: /nodes/latte_local/compile + ~ Routed to: {:controller=>"nodes", :format=>nil, :action=>"compile", :id=>"latte_local"} + ~ Params: {"format"=>nil, "action"=>"compile", "id"=>"latte_local", "controller"=>"nodes"} + ~ {:dispatch_time=>0.35835, :action_time=>0.358026, :before_filters_time=>3.9e-05, :after_filters_time=>1.5e-05} + ~ + + ~ Using 'share-nothing' cookie sessions (4kb limit per client) + ~ {:before_filters_time=>0.000138, :after_filters_time=>9.0e-06, :action_time=>0.001826} + ~ {:before_filters_time=>9.3e-05, :after_filters_time=>9.0e-06, :action_time=>0.000342} + ~ {:before_filters_time=>0.000177, :after_filters_time=>1.0e-05, :action_time=>0.000479} + ~ {:before_filters_time=>0.000149, :after_filters_time=>9.0e-06, :action_time=>0.000427} + ~ {:before_filters_time=>0.000123, :after_filters_time=>1.0e-05, :action_time=>0.000425} + ~ Redirecting to: /openid/consumer + ~ {:after_filters_time=>1.0e-05, :action_time=>0.001232} + ~ Redirecting to: /openid/consumer + ~ {:after_filters_time=>6.0e-06, :action_time=>0.000707} + ~ Redirecting to: /openid/consumer + ~ {:after_filters_time=>7.0e-06, :action_time=>0.000735} + ~ Redirecting to: /openid/consumer + ~ {:after_filters_time=>7.0e-06, :action_time=>0.00067} + ~ Redirecting to: /openid/consumer + ~ {:after_filters_time=>6.0e-06, :action_time=>0.000646} + ~ Redirecting to: /openid/consumer + ~ {:after_filters_time=>6.0e-06, :action_time=>0.000644} + ~ Redirecting to: /openid/consumer + ~ {:after_filters_time=>5.0e-06, :action_time=>0.000634} + ~ Redirecting to: /openid/consumer + ~ {:after_filters_time=>9.0e-06, :action_time=>0.000728} + ~ Using 'share-nothing' cookie sessions (4kb limit per client) + ~ Using 'share-nothing' cookie sessions (4kb limit per client) diff --git a/lib/chef_server/public/images/merb.jpg b/lib/chef_server/public/images/merb.jpg Binary files differnew file mode 100644 index 0000000000..a19dcf4048 --- /dev/null +++ b/lib/chef_server/public/images/merb.jpg diff --git a/lib/chef_server/public/stylesheets/master.css b/lib/chef_server/public/stylesheets/master.css new file mode 100644 index 0000000000..70580148a7 --- /dev/null +++ b/lib/chef_server/public/stylesheets/master.css @@ -0,0 +1,153 @@ +body { + font-family: Arial, Verdana, sans-serif; + font-size: 12px; + background-color: #fff; + margin: ; +} +html { + height: 100%; + margin-bottom: 1px; +} +#container { + width: 80%; + text-align: left; + background-color: #fff; + margin-right: auto; + margin-left: auto; +} +#header-container { + width: 100%; + padding-top: 15px; +} +#header-container h1, #header-container h2 { + margin-left: 6px; + margin-bottom: 6px; +} +.spacer { + width: 100%; + height: 15px; +} +hr { + border: 0px; + color: #ccc; + background-color: #cdcdcd; + height: 1px; + width: 100%; + text-align: left; +} +h1 { + font-size: 28px; + color: #c55; + background-color: #fff; + font-family: Arial, Verdana, sans-serif; + font-weight: 300; +} +h2 { + font-size: 15px; + color: #999; + font-family: Arial, Verdana, sans-serif; + font-weight: 300; + background-color: #fff; +} +h3 { + color: #4d9b12; + font-size: 15px; + text-align: left; + font-weight: 300; + padding: 5px; + margin-top: 5px; +} + +#left-container { + float: left; + width: 250px; + background-color: #FFFFFF; + color: black; +} + +#left-container h3 { + color: #c55; +} + +#main-container { + margin: 5px 5px 5px 260px; + padding: 15px; + border-left: 1px solid silver; + min-height: 400px; +} +p { + color: #000; + background-color: #fff; + line-height: 20px; + padding: 5px; +} +a { + color: #4d9b12; + background-color: #fff; + text-decoration: none; +} +a:hover { + color: #4d9b12; + background-color: #fff; + text-decoration: underline; +} +#footer-container { + clear: both; + font-size: 12px; + font-family: Verdana, Arial, sans-serif; +} +.right { + float: right; + font-size: 100%; + margin-top: 5px; + color: #999; + background-color: #fff; +} +.left { + float: left; + font-size: 100%; + margin-top: 5px; + color: #999; + background-color: #fff; +} +#main-container ul { + margin-left: 3.0em; +} + +div.resource_collection { + border: 1px solid #999; + float: left; + clear: both; + margin: 10px; + padding: 5px; +} + +div.resource { + border-top: 1px solid #999; + float: left; + clear: both; +} + +div.attr_group { + float: left; + clear: both; +} + +td.attr_name { + font-weight: bold; + margin-right: 10px; + border-right: 1px solid #999; +} + +td.attr_value { + padding-left: 5px; + border-top: 1px solid #999; +} + +div.node { + float: left; + clear: both; + margin: 10px; + padding: 5px; + border: 1px solid #999; +}
\ No newline at end of file diff --git a/lib/chef_server/views/exceptions/bad_request.json.erb b/lib/chef_server/views/exceptions/bad_request.json.erb new file mode 100644 index 0000000000..f266cf99b9 --- /dev/null +++ b/lib/chef_server/views/exceptions/bad_request.json.erb @@ -0,0 +1 @@ +<%= { :error => params[:exception], :code => 400 }.to_json %>
\ No newline at end of file diff --git a/lib/chef_server/views/exceptions/internal_server_error.html.erb b/lib/chef_server/views/exceptions/internal_server_error.html.erb new file mode 100644 index 0000000000..aadbfad350 --- /dev/null +++ b/lib/chef_server/views/exceptions/internal_server_error.html.erb @@ -0,0 +1,216 @@ +<html> +<head> + <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> + <title><%= @exception_name %></title> + <style type="text/css" media="screen"> + body { + font-family:arial; + font-size:11px; + } + h1 { + font-size:48px; + letter-spacing:-4px; + margin:0; + line-height:36px; + color:#333; + } + h1 sup { + font-size: 0.5em; + } + h1 sup.error_500, h1 sup.error_400 { + color:#990E05; + } + h1 sup.error_100, h1 sup.error_200 { + color:#00BF10; + } + h1 sup.error_300 { + /* pretty sure you cant 'see' status 300 + errors but if you could I think they + would be blue */ + color:#1B2099; + } + h2 { + font-size:36px; + letter-spacing:-3px; + margin:0; + line-height:28px; + color:#444; + } + a, a:visited { + color:#00BF10; + } + .internalError { + width:800px; + margin:50px auto; + } + .header { + border-bottom:10px solid #333; + margin-bottom:1px; + background-image: url("data:image/gif;base64,R0lGODlhAwADAIAAAP///8zMzCH5BAAAAAAALAAAAAADAAMAAAIEBHIJBQA7"); + padding:20px; + } + table.trace { + width:100%; + font-family:courier, monospace; + letter-spacing:-1px; + border-collapse: collapse; + border-spacing:0; + } + table.trace tr td{ + padding:0; + height:26px; + font-size:13px; + vertical-align:middle; + } + table.trace tr.file{ + border-top:2px solid #fff; + background-color:#F3F3F3; + } + table.trace tr.source { + background-color:#F8F8F8; + display:none; + } + table.trace .open tr.source { + display:table-row; + } + table.trace tr.file td.expand { + width:23px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAXCAIAAABvSEP3AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAdVJREFUeNqMVL+TwUAYxaRIOlEhlZHGDAUzzOQ61+AqXMV1lJSU7q/QRqm8KFUcJTNn5qJkaPyoKKVz7y4mF8na5Kt29tt9+/Z97/u81+vVQ4r9frdarS6Xi7ETDIZisRjxMGPfmk4niNPpZE+xLAugbPaZ53nzvtfMBe/3+/3dbuehBrAKhZdUKkVAWa9Xsiybv0CPZDJZLr/qa5/BwgwRjYqOKIvFYjQa/aNommZh0Ww2K5UqzwfoQOPxaLPZ3FAmk0+7lplMpt1u53J5OpBOR0eZEE9wHJfP5zud93g88QhluwWbjW+5VOmKBgKBer3eaDTDYeGBQF8+x7rqIYoiPgixWJazpA6HA+MSxRArkUgMh0M409g8Ho8+9wYxxCqVSq1W26EDHGM2m4HOHQrEc38f/Yn7cLmlIRhBENzcx8cVRZnPZ/YUep2BWkjTIfA+PKVpZAXR5QxsjiqCKvGEqqp443w+0dvy17swqD0HB3S73V5PpkNg1qBqt8kwGCjmPkinM0QJbIoEa7U6UG6ToVgs4V9G2g0ESoP5Aoi7KYX5oCgf8IKbkvn9/mr1LRQKESamzgJy0g0tSZIuB3nuGqRU9Vv9C4sKkUhEkp4soxvxI8AAhWrrtXa3X8EAAAAASUVORK5CYII=); + background-position:top left; + background-repeat:no-repeat; + } + table.trace .open tr.file td.expand { + width:19px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAB1CAIAAAAqdO2mAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAXZJREFUeNrslK1ywkAUhcMOBomEOiSdqLxEBJX0NaijOsjyHGGmCGyQQYaiiiw4gktkcOmZbpsuuzQ/M5XnqJ2d3S/n3nM3rTzPLUP7/Tt0+pLcGQwG3W53OLyHzPMtjYL7q9UqSRLrD4E1Gj1orCvKYuFHUWTVkOM44/HjDcp8/lL4r6NerzeZPMm1KFw0QkDn83m5fP2lHA4fNQvRtNvtjsfDd0WzmSfb2e/fdTqdOvdh/HLJZLOn0+d2HJ+KRGzbdl23EpFlmed5cp2maRzHQq1lvQ5KMi6EUZBGfup6E1pTfd+vrGW7jbQ2C9hTt9BpqNyIWaAwAy6xg2eBz5iRC/NomiZhGN5sqmnkauo0BUGgVQoBjQ80oCACgNQdZHfTYBkF2mxCtWWAqunWpahxIDUt3QYUxIFQpJHyIWpXjinabKbbwItMHT+NyjchrP8QKaSQQgoppJBCCimkkEIKKaSQQgoppJBCCimkkEIKKaSo+hRgAEFD17X08O2NAAAAAElFTkSuQmCC); + background-position:top left; + background-repeat:no-repeat; + } + table.trace tr.source td.collapse { + width:19px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAB1CAIAAAAqdO2mAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAVxJREFUeNrs0zFygkAUBmBlUkgJHdABlQwVkVJKKUxBYWbkALTxMJwhltyDFkss03IF8pudIcwaDaDl/6pd2P327b7d+eHwMXs4lNkzggoVKlSoUKFChQoVKlSoUKFChQoVKlSoUKFChQqVEYqm6ft9+qiSJEkYho7jTlcw2fd9NOI4nq4gEdFwXXe1Cqco63VkWVbXRTqLhTpOwQRpF7quR1E0TgGhqvLKUFCyoQqG/rks3O6kZKW/eRFpevOCoGTXVTcMQ5EyxyDEkML1c5RzuZOICIyXqn7JBVez6282MWrx731HOv2qB8Hri2lamNk0DfpVVdV1Peodappmmua8bdvzuc7zfNprzrLMth1FnGh/X8MjCAIQv/cFz/+65PcDh7rbvYv2ZUfdj+PxsyzLgVl0hKwgTqeqKApx2LeOc7t98zyv/1FWOgvx9RPii23bmL9cetJ8Ed8CDAC6aFW8bCzFhwAAAABJRU5ErkJggg==); + background-position:bottom left; + background-repeat:no-repeat; + background-color:#6F706F; + } + table.trace tr td.path { + padding-left:10px; + } + table.trace tr td.code { + padding-left:35px; + white-space: pre; + line-height:9px; + padding-bottom:10px; + } + table.trace tr td.code em { + font-weight:bold; + color:#00BF10; + } + table.trace tr td.code a { + width: 20px; + float: left; + } + table.trace tr td.code .more { + color:#666; + } + table.trace tr td.line { + width:30px; + text-align:right; + padding-right:4px; + } + .footer { + margin-top:5px; + font-size:11px; + color:#444; + text-align:right; + } + </style> +</head> +<body> + <div class="internalError"> + + <div class="header"> + <h1><%= @exception_name %> <sup class="error_<%= @exception.class::STATUS %>"><%= @exception.class::STATUS %></sup></h1> + <% if show_details = ::Merb::Config[:exception_details] -%> + <h2><%= @exception.message %></h2> + <% else -%> + <h2>Sorry about that...</h2> + <% end -%> + <h3>Parameters</h3> + <ul> + <% params[:original_params].each do |param, value| %> + <li><strong><%= param %>:</strong> <%= value.inspect %></li> + <% end %> + <%= "<li>None</li>" if params[:original_params].empty? %> + </ul> + + <h3>Session</h3> + <ul> + <% params[:original_session].each do |param, value| %> + <li><strong><%= param %>:</strong> <%= value.inspect %></li> + <% end %> + <%= "<li>None</li>" if params[:original_session].empty? %> + </ul> + + <h3>Cookies</h3> + <ul> + <% params[:original_cookies].each do |param, value| %> + <li><strong><%= param %>:</strong> <%= value.inspect %></li> + <% end %> + <%= "<li>None</li>" if params[:original_cookies].empty? %> + </ul> + </div> + + <% if show_details %> + <table class="trace"> + <% @exception.backtrace.each_with_index do |line, index| %> + <tbody class="close"> + <tr class="file"> + <td class="expand"> + </td> + <td class="path"> + <%= (line.match(/^([^:]+)/)[1] rescue 'unknown').sub(/\/((opt|usr)\/local\/lib\/(ruby\/)?(gems\/)?(1.8\/)?(gems\/)?|.+\/app\/)/, '') %> + <% unless line.match(/\.erb:/) %> + in "<strong><%= line.match(/:in `(.+)'$/)[1] rescue '?' %></strong>" + <% else %> + (<strong>ERB Template</strong>) + <% end %> + </td> + <td class="line"> + <a href="txmt://open?url=file://<%=file = (line.match(/^([^:]+)/)[1] rescue 'unknown')%>&line=<%= lineno = line.match(/:([0-9]+):/)[1] rescue '?' %>"><%=lineno%></a> + </td> + </tr> + <tr class="source"> + <td class="collapse"> + </td> + <td class="code" colspan="2"><% (__caller_lines__(file, lineno, 5) rescue []).each do |llineno, lcode, lcurrent| %> +<a href="txmt://open?url=file://<%=file%>&line=<%=llineno%>"><%= llineno %></a><%='<em>' if llineno==lineno.to_i %><%= lcode.size > 90 ? CGI.escapeHTML(lcode[0..90])+'<span class="more">......</span>' : CGI.escapeHTML(lcode) %><%='</em>' if llineno==lineno.to_i %> +<% end %> + +</td> + </tr> + </tbody> + <% end %> + </table> + <script type="text/javascript" charset="utf-8"> + // swop the open & closed classes + els = document.getElementsByTagName('td'); + for(i=0; i<els.length; i++){ + if(els[i].className=='expand' || els[i].className=='collapse'){ + els[i].onclick = function(e){ + tbody = this.parentNode.parentNode; + if(tbody.className=='open'){ + tbody.className='closed'; + }else{ + tbody.className='open'; + } + } + } + } + </script> + <% end %> + <div class="footer"> + lots of love, from <a href="#">merb</a> + </div> + </div> +</body> +</html>
\ No newline at end of file diff --git a/lib/chef_server/views/exceptions/not_acceptable.html.erb b/lib/chef_server/views/exceptions/not_acceptable.html.erb new file mode 100644 index 0000000000..f632712bb2 --- /dev/null +++ b/lib/chef_server/views/exceptions/not_acceptable.html.erb @@ -0,0 +1,63 @@ +<div id="container"> + <div id="header-container"> + <img src="/images/merb.jpg" /> + <!-- <h1>Mongrel + Erb</h1> --> + <h2>pocket rocket web framework</h2> + <hr /> + </div> + + <div id="left-container"> + <h3>Exception:</h3> + <p><%= params[:exception] %></p> + </div> + + <div id="main-container"> + <h3>Why am I seeing this page?</h3> + <p>Merb couldn't find an appropriate content_type to return, + based on what you said was available via provides() and + what the client requested.</p> + + <h3>How to add a mime-type</h3> + <pre><code> + Merb.add_mime_type :pdf, :to_pdf, %w[application/pdf], "Content-Encoding" => "gzip" + </code></pre> + <h3>What this means is:</h3> + <ul> + <li>Add a mime-type for :pdf</li> + <li>Register the method for converting objects to PDF as <code>#to_pdf</code>.</li> + <li>Register the incoming mime-type "Accept" header as <code>application/pdf</code>.</li> + <li>Specify a new header for PDF types so it will set <code>Content-Encoding</code> to gzip.</li> + </ul> + + <h3>You can then do:</h3> + <pre><code> + class Foo < Application + provides :pdf + end + </code></pre> + + <h3>Where can I find help?</h3> + <p>If you have any questions or if you can't figure something out, please take a + look at our <a href="http://merbivore.com/"> project page</a>, + feel free to come chat at irc.freenode.net, channel #merb, + or post to <a href="http://groups.google.com/group/merb">merb mailing list</a> + on Google Groups.</p> + + <h3>What if I've found a bug?</h3> + <p>If you want to file a bug or make your own contribution to Merb, + feel free to register and create a ticket at our + <a href="http://merb.lighthouseapp.com/">project development page</a> + on Lighthouse.</p> + + <h3>How do I edit this page?</h3> + <p>You can change what people see when this happens by editing <tt>app/views/exceptions/not_acceptable.html.erb</tt>.</p> + + </div> + + <div id="footer-container"> + <hr /> + <div class="left"></div> + <div class="right">© 2007 the merb dev team</div> + <p> </p> + </div> +</div> diff --git a/lib/chef_server/views/exceptions/not_found.html.erb b/lib/chef_server/views/exceptions/not_found.html.erb new file mode 100644 index 0000000000..388c72c31d --- /dev/null +++ b/lib/chef_server/views/exceptions/not_found.html.erb @@ -0,0 +1,47 @@ +<div id="container"> + <div id="header-container"> + <img src="/images/merb.jpg" /> + <!-- <h1>Mongrel + Erb</h1> --> + <h2>pocket rocket web framework</h2> + <hr /> + </div> + + <div id="left-container"> + <h3>Exception:</h3> + <p><%= params[:exception] %></p> + </div> + + <div id="main-container"> + <h3>Welcome to Merb!</h3> + <p>Merb is a light-weight MVC framework written in Ruby. We hope you enjoy it.</p> + + <h3>Where can I find help?</h3> + <p>If you have any questions or if you can't figure something out, please take a + look at our <a href="http://merbivore.com/"> project page</a>, + feel free to come chat at irc.freenode.net, channel #merb, + or post to <a href="http://groups.google.com/group/merb">merb mailing list</a> + on Google Groups.</p> + + <h3>What if I've found a bug?</h3> + <p>If you want to file a bug or make your own contribution to Merb, + feel free to register and create a ticket at our + <a href="http://merb.lighthouseapp.com/">project development page</a> + on Lighthouse.</p> + + <h3>How do I edit this page?</h3> + <p>You're seeing this page because you need to edit the following files: + <ul> + <li>config/router.rb <strong><em>(recommended)</em></strong></li> + <li>app/views/exceptions/not_found.html.erb <strong><em>(recommended)</em></strong></li> + <li>app/views/layout/application.html.erb <strong><em>(change this layout)</em></strong></li> + </ul> + </p> + </div> + + <div id="footer-container"> + <hr /> + <div class="left"></div> + <div class="right">© 2007 the merb dev team</div> + <p> </p> + </div> +</div> diff --git a/lib/chef_server/views/layout/application.html.haml b/lib/chef_server/views/layout/application.html.haml new file mode 100644 index 0000000000..f04f299d2c --- /dev/null +++ b/lib/chef_server/views/layout/application.html.haml @@ -0,0 +1,22 @@ +!!! XML +!!! +%html + %head + %title Chef Server + %meta{"http-equiv" => "content-type", :content => "text/html; charset=utf-8" } + %link{:rel => "stylesheet", :href => "/stylesheets/master.css", :type => "text/css", :media => "screen", :charset => "utf-8" } + %body + .header + %a{:href => url(:nodes) } Nodes + | + %a{:href => url(:registrations)} Registrations + - if session[:openid] + | + %a{:href => url(:openid_consumer_logout)}= "Logout #{h session[:openid]}" + = "(#{session[:level].to_s})" + - else + | + %a{:href => url(:openid_consumer)} Login + = catch_content :for_layout + +
\ No newline at end of file diff --git a/lib/chef_server/views/nodes/_action.html.haml b/lib/chef_server/views/nodes/_action.html.haml new file mode 100644 index 0000000000..a809a6d70c --- /dev/null +++ b/lib/chef_server/views/nodes/_action.html.haml @@ -0,0 +1,13 @@ +%table + - actions.each do |action, resource_hash| + %tr + %td.action_name= action.to_s + %td.action_resources + %table + - resource_hash.keys.sort{ |a,b| a.to_s <=> b.to_s }.each do |rk| + %tr + %td.action_when= rk.to_s + %td + - resource_hash[rk].each do |resource| + = partial(:resource, :resource => resource) +
\ No newline at end of file diff --git a/lib/chef_server/views/nodes/_node.html.haml b/lib/chef_server/views/nodes/_node.html.haml new file mode 100644 index 0000000000..7dce36488f --- /dev/null +++ b/lib/chef_server/views/nodes/_node.html.haml @@ -0,0 +1,11 @@ +.node + %h1 + = "Node #{h node.name}" + %h2 Actions + %a{ :href => url(:compile_node, { :id => node_escape(node.name) }) } Compile Node + %h2 Recipes + %ol + = recipe_list(node) + %h2 Attributes + %ol + = attribute_list(node) diff --git a/lib/chef_server/views/nodes/_resource.html.haml b/lib/chef_server/views/nodes/_resource.html.haml new file mode 100644 index 0000000000..7b9776b816 --- /dev/null +++ b/lib/chef_server/views/nodes/_resource.html.haml @@ -0,0 +1,22 @@ +.resource + %h3= "#{h resource.to_s} (#{resource.class})" + %table + - resource.instance_variables.sort.each do |v| + - attr_name = v.gsub(/\@/, "") + - unless attr_name == "collection" + %tr.attr_group + %td.attr_name + = "#{h attr_name}" + %td.attr_value + - value = resource.instance_variable_get(v) + - if value.kind_of?(String) + = "#{h value}" + - elsif value.kind_of?(Array) + = "#{h value.join(", ")}" + - elsif value.kind_of?(Symbol) + = "#{h value.to_s}" + - elsif attr_name == "actions" + = partial(:action, :actions => value) + - else + = "#{h value.inspect}" + diff --git a/lib/chef_server/views/nodes/compile.html.haml b/lib/chef_server/views/nodes/compile.html.haml new file mode 100644 index 0000000000..5656447ea8 --- /dev/null +++ b/lib/chef_server/views/nodes/compile.html.haml @@ -0,0 +1,5 @@ += partial(:node, :node => @output[:node]) +.resource_collection + %h1 Resource Collection + - @output[:collection].each do |resource| + = partial(:resource, :resource => resource) diff --git a/lib/chef_server/views/nodes/index.html.haml b/lib/chef_server/views/nodes/index.html.haml new file mode 100644 index 0000000000..667e1c7317 --- /dev/null +++ b/lib/chef_server/views/nodes/index.html.haml @@ -0,0 +1,9 @@ +%h1 Node List +- @node_list.each do |node| + .node + %a{ :href => url(:node, { :id => node.gsub(/\./, "_") }) } + = node + %form{ :method => "post", :action => url(:node, { :id => node.gsub(/\./, "_") })} + %input{ :type => "hidden", :name => "_method", :value => "delete" } + %input{ :type => "submit", :name => "Delete", :value => "Delete" } +
\ No newline at end of file diff --git a/lib/chef_server/views/nodes/show.html.haml b/lib/chef_server/views/nodes/show.html.haml new file mode 100644 index 0000000000..94708af6d3 --- /dev/null +++ b/lib/chef_server/views/nodes/show.html.haml @@ -0,0 +1 @@ += partial(:node, :node => @node)
\ No newline at end of file diff --git a/lib/chef_server/views/openid_consumer/index.html.haml b/lib/chef_server/views/openid_consumer/index.html.haml new file mode 100644 index 0000000000..576ef8d787 --- /dev/null +++ b/lib/chef_server/views/openid_consumer/index.html.haml @@ -0,0 +1,25 @@ +%h1 OpenID Relying Party +-if session[:alert] + .alert= h session[:alert] +-if session[:error] + .error= h session[:error] +-if session[:success] + .success= h session[:success] +#verify-form + %form{ :method => "get", "accept-charset" => "UTF-8", :action => url(:openid_consumer_start) } + Identifier: + %input.openid{ :type => "text", :name => "openid_identifier" }/ + %input{ :type => "submit", :value => "Verify"}/ + %br + %input#immediate{ :name => "immediate", :type => "checkbox" }/ + %label{:for => "immediate"} Use immediate mode + %br + %input#immediate{ :name => "use_sreg", :type => "checkbox" }/ + %label{:for => "use_sreg"} Request registration data + %br + %input#immediate{ :name => "use_pape", :type => "checkbox" }/ + %label{:for => "use_pape"} Request phishing-resistent auth policy + %br + %input#immediate{ :name => "force_post", :type => "checkbox" }/ + %label{:for => "force_post"} Force the transaction to POST + %br diff --git a/lib/chef_server/views/openid_consumer/start.html.haml b/lib/chef_server/views/openid_consumer/start.html.haml new file mode 100644 index 0000000000..75ed9a9257 --- /dev/null +++ b/lib/chef_server/views/openid_consumer/start.html.haml @@ -0,0 +1,4 @@ +<%= @form_text %> +<script type="text/javascript"> +document.getElementById('openid_form').submit(); +</script>
\ No newline at end of file diff --git a/lib/chef_server/views/openid_login/index.html.haml b/lib/chef_server/views/openid_login/index.html.haml new file mode 100644 index 0000000000..17ae69017a --- /dev/null +++ b/lib/chef_server/views/openid_login/index.html.haml @@ -0,0 +1,6 @@ +%h1 Login +#login-form + %form{ :method => "get", :action => url(:openid_login_submit) } + %input{ :type => "text", :name => "username" }/ + %input{ :type => "submit", :value => "Log In"}/ +
\ No newline at end of file diff --git a/lib/chef_server/views/openid_register/index.html.haml b/lib/chef_server/views/openid_register/index.html.haml new file mode 100644 index 0000000000..fe4798c59d --- /dev/null +++ b/lib/chef_server/views/openid_register/index.html.haml @@ -0,0 +1,15 @@ +%h1 Registered OpenID Nodes List +%table +- @registered_nodes.each do |node| + %tr + %td + %a{ :href => url(:registration, { :id => node.name }) } + = h node.name + %td + - if session[:level] == :admin + %form{ :method => "post", :action => url(:validate_registration, { :id => node.name })} + - submit_name = node.validated ? "Invalidate" : "Validate" + %input{ :type => "submit", :name => submit_name, :value => submit_name } + %form{ :method => "post", :action => url(:registration, { :id => node.name })} + %input{ :type => "hidden", :name => "_method", :value => "delete" } + %input{ :type => "submit", :name => "Delete", :value => "Delete" } diff --git a/lib/chef_server/views/openid_register/show.html.haml b/lib/chef_server/views/openid_register/show.html.haml new file mode 100644 index 0000000000..cfd38e8963 --- /dev/null +++ b/lib/chef_server/views/openid_register/show.html.haml @@ -0,0 +1,5 @@ +%h1= "Registered OpenID Node #{@registered_node.name}" +%ol + %li + %a{ :href => url(:openid_node , { :id => @registered_node.name.gsub(/\./, "_") }) } OpenID URL + %li= "Validated: #{@registered_node.validated}" diff --git a/lib/chef_server/views/openid_server/decide.html.haml b/lib/chef_server/views/openid_server/decide.html.haml new file mode 100644 index 0000000000..8082a5068d --- /dev/null +++ b/lib/chef_server/views/openid_server/decide.html.haml @@ -0,0 +1,27 @@ +%form{:method => "post", :action => url(:openid_server_decision)} + %table + %tr + %td Site: + %td= @oidreq.trust_root + - if @oidreq.id_select + %tr + %td{:colspan => "2"} + You entered the server identifier at the relying party. + You will need to send an identifier of your choosing. + Enter a username and password below. + %tr + %td Identity to send: + %td + %input{:type => "text", :name => "id_to_send", :size => "25"} + - else + %tr + %td Identity: + %td= @oidreq.identity + %tr + %td + %label{:for => "password"} Password: + %td + %input{:type => "password", :name => "password"} + %input{:type => "submit", :name => "submit", :value => "Authenticate"} + %input{:type => "submit", :name => "cancel", :value => "Cancel"} + diff --git a/log/chef-server.log b/log/chef-server.log new file mode 100644 index 0000000000..eabfde15a0 --- /dev/null +++ b/log/chef-server.log @@ -0,0 +1,9 @@ +Mon, 16 Jun 2008 01:13:56 GMT ~ info ~ Logfile created + ~ Compiling routes... + ~ Using 'share-nothing' cookie sessions (4kb limit per client) + ~ Using Mongrel adapter + ~ Compiling routes... + ~ Using 'share-nothing' cookie sessions (4kb limit per client) + ~ Using Mongrel adapter + ~ Using 'share-nothing' cookie sessions (4kb limit per client) + ~ Using Mongrel adapter diff --git a/log/merb_test.log b/log/merb_test.log new file mode 100644 index 0000000000..dae0e5d9dd --- /dev/null +++ b/log/merb_test.log @@ -0,0 +1,7 @@ +Tue, 03 Jun 2008 04:33:52 GMT ~ info ~ Logfile created + ~ Not Using Sessions + ~ Not Using Sessions + ~ Not Using Sessions + ~ Not Using Sessions + ~ Not Using Sessions + ~ Not Using Sessions diff --git a/spec/chef_server/controllers/log/merb_test.log b/spec/chef_server/controllers/log/merb_test.log new file mode 100644 index 0000000000..86fbe4b9cb --- /dev/null +++ b/spec/chef_server/controllers/log/merb_test.log @@ -0,0 +1,4 @@ +Tue, 27 May 2008 00:52:34 GMT ~ info ~ Logfile created + ~ Not Using Sessions + ~ Not Using Sessions + ~ Not Using Sessions diff --git a/spec/chef_server/controllers/nodes_spec.rb b/spec/chef_server/controllers/nodes_spec.rb new file mode 100644 index 0000000000..a86fa4138c --- /dev/null +++ b/spec/chef_server/controllers/nodes_spec.rb @@ -0,0 +1,214 @@ +require File.join(File.dirname(__FILE__), "..", 'spec_helper.rb') + +describe Nodes, "index action" do + it "should get a list of all the nodes" do + Chef::Node.should_receive(:list).and_return(["one"]) + dispatch_to(Nodes, :index) do |c| + c.stub!(:display) + end + end + + it "should send a list of nodes to display" do + Chef::Node.stub!(:list).and_return(["one"]) + dispatch_to(Nodes, :index) do |c| + c.should_receive(:display).with(["one"]) + end + end +end + +describe Nodes, "show action" do + it "should load a node from the filestore based on the id" do + node = stub("Node", :null_object => true) + Chef::Node.should_receive(:load).with("bond").once.and_return(node) + dispatch_to(Nodes, :show, { :id => "bond" }) do |c| + c.should_receive(:display).with(node).once.and_return(true) + end + end + + it "should return 200 on a well formed request" do + node = stub("Node", :null_object => true) + Chef::Node.should_receive(:load).with("bond").once.and_return(node) + controller = dispatch_to(Nodes, :show, { :id => "bond" }) do |c| + c.stub!(:display) + end + controller.status.should eql(200) + end + + it "should raise a BadRequest if the id is not found" do + Chef::Node.should_receive(:load).with("bond").once.and_raise(RuntimeError) + lambda { + dispatch_to(Nodes, :show, { :id => "bond" }) + }.should raise_error(Merb::ControllerExceptions::BadRequest) + end +end + +describe Nodes, "create action" do + it "should create a node from an inflated object" do + mnode = mock("Node", :null_object => true) + mnode.stub!(:name).and_return("bond") + mnode.should_receive(:save).once.and_return(true) + controller = dispatch_to(Nodes, :create) do |c| + c.stub!(:params).and_return({ "inflated_object" => mnode }) + c.stub!(:session).and_return({ + :openid => 'http://localhost/openid/server/node/bond', + :level => :node, + :node_name => "bond", + }) + c.stub!(:display) + end + controller.status.should eql(202) + end + + it "should raise an exception if it cannot inflate an object" do + lambda { + dispatch_to(Nodes, :create) do |c| + c.stub!(:params).and_return({ }) + end + }.should raise_error(Merb::Controller::BadRequest) + end +end + +describe Nodes, "update action" do + it "should update a node from an inflated object" do + mnode = mock("Node", :null_object => true) + mnode.stub!(:name).and_return("one") + Chef::FileStore.should_receive(:store).with("node", "one", mnode).once.and_return(true) + controller = dispatch_to(Nodes, :update, { :id => "one" }) do |c| + c.stub!(:session).and_return({ + :openid => 'http://localhost/openid/server/node/one', + :level => :node, + :node_name => "one", + }) + c.stub!(:params).and_return({ "inflated_object" => mnode }) + c.stub!(:display) + end + controller.status.should eql(202) + end + + it "should raise an exception if it cannot inflate an object" do + lambda { dispatch_to(Nodes, :update) }.should raise_error(Merb::Controller::BadRequest) + end +end + +describe Nodes, "destroy action" do + def do_destroy + dispatch_to(Nodes, :destroy, { :id => "one" }) do |c| + c.stub!(:display) + end + end + + it "should load the node it's about to destroy from the filestore" do + mnode = stub("Node", :null_object => true) + Chef::FileStore.should_receive(:load).with("node", "one").once.and_return(mnode) + Chef::FileStore.stub!(:delete) + do_destroy + end + + it "should raise an exception if it cannot find the node to destroy" do + Chef::FileStore.should_receive(:load).with("node", "one").once.and_raise(RuntimeError) + lambda { do_destroy }.should raise_error(Merb::Controller::BadRequest) + end + + it "should remove the node from the filestore" do + mnode = stub("Node", :null_object => true) + Chef::FileStore.stub!(:load).with("node", "one").and_return(mnode) + Chef::FileStore.should_receive(:delete).with("node", "one") + do_destroy + end + + it "should remove the node from the search index" do + mnode = stub("Node", :null_object => true) + Chef::FileStore.stub!(:load).with("node", "one").and_return(mnode) + Chef::FileStore.stub!(:delete) + do_destroy + end + + it "should return the node it just deleted" do + mnode = stub("Node", :null_object => true) + Chef::FileStore.stub!(:load).with("node", "one").and_return(mnode) + Chef::FileStore.stub!(:delete) + dispatch_to(Nodes, :destroy, { :id => "one" }) do |c| + c.should_receive(:display).once.with(mnode) + end + end + + it "should return a status of 202" do + mnode = stub("Node", :null_object => true) + Chef::FileStore.stub!(:load).with("node", "one").and_return(mnode) + Chef::FileStore.stub!(:delete) + controller = do_destroy + controller.status.should eql(202) + end +end + +describe Nodes, "compile action" do + before(:each) do + @compile = stub("Compile", :null_object => true) + @node = stub("Node", :null_object => true) + @node.stub!(:[]).and_return(true) + @node.stub!(:[]=).and_return(true) + @node.stub!(:recipes).and_return([]) + @compile.stub!(:load_definitions).and_return(true) + @compile.stub!(:load_recipes).and_return(true) + @compile.stub!(:collection).and_return([]) + @compile.stub!(:node, @node) + @compile.stub!(:load_node).and_return(true) + @stored_node = stub("Stored Node", :null_object => true) + end + + def do_compile + Chef::FileStore.stub!(:store).and_return(true) + Chef::FileStore.stub!(:load).and_return(@stored_node) + Chef::Compile.stub!(:new).and_return(@compile) + dispatch_to(Nodes, :compile, { :id => "one" }) do |c| + c.stub!(:display) + end + end + + it "should load the node from the node resource" do + @compile.should_receive(:load_node).with("one").and_return(true) + do_compile + end + + it "should merge the data with the currently stored node" do + node1 = Chef::Node.new + node1.name "adam" + node1.music "crowe" + node1.recipes << "monkey" + @compile.stub!(:node).and_return(node1) + @stored_node = Chef::Node.new + @stored_node.name "adam" + @stored_node.music "crown" + @stored_node.woot "woot" + @stored_node.recipes << "monkeysoup" + do_compile + node1.name.should eql("adam") + node1.music.should eql("crown") + node1.woot.should eql("woot") + node1.recipes.should eql([ "monkey", "monkeysoup" ]) + end + + it "should load definitions" do + @compile.should_receive(:load_definitions) + do_compile + end + + it "should load recipes" do + @compile.should_receive(:load_recipes) + do_compile + end + + it "should display the collection and node object" do + Chef::FileStore.stub!(:load).and_return(@stored_node) + Chef::Compile.stub!(:new).and_return(@compile) + dispatch_to(Nodes, :compile, { :id => "one" }) do |c| + c.should_receive(:display).with({ :collection => [], :node => nil }) + end + end + + it "should return 200" do + controller = do_compile + controller.status.should eql(200) + end + +end
\ No newline at end of file diff --git a/spec/chef_server/controllers/openid_consumer_spec.rb b/spec/chef_server/controllers/openid_consumer_spec.rb new file mode 100644 index 0000000000..a93cad4191 --- /dev/null +++ b/spec/chef_server/controllers/openid_consumer_spec.rb @@ -0,0 +1,29 @@ +require File.join(File.dirname(__FILE__), "..", 'spec_helper.rb') + +describe OpenidConsumer, "check_valid_openid_provider method" do + it "should confirm the openid provider if the openid_providers config is nil" do + Chef::Config[:openid_providers] = nil + c = OpenidConsumer.new(true) + c.send(:check_valid_openid_provider, "monkeyid").should eql(true) + end + + it "should return true if the openid provider is in openid_providers list" do + Chef::Config[:openid_providers] = [ 'monkeyid' ] + c = OpenidConsumer.new(true) + c.send(:check_valid_openid_provider, "monkeyid").should eql(true) + end + + it "should return true if the openid provider is in openid_providers list with http://" do + Chef::Config[:openid_providers] = [ 'monkeyid' ] + c = OpenidConsumer.new(true) + c.send(:check_valid_openid_provider, "http://monkeyid").should eql(true) + end + + it "should raise an exception if the openid provider is not in openid_providers list" do + Chef::Config[:openid_providers] = [ 'monkeyid' ] + c = OpenidConsumer.new(true) + lambda { + c.send(:check_valid_openid_provider, "monkey") + }.should raise_error(Merb::Controller::Unauthorized) + end +end
\ No newline at end of file diff --git a/spec/chef_server/controllers/openid_register_spec.rb b/spec/chef_server/controllers/openid_register_spec.rb new file mode 100644 index 0000000000..6822722868 --- /dev/null +++ b/spec/chef_server/controllers/openid_register_spec.rb @@ -0,0 +1,93 @@ +require File.join(File.dirname(__FILE__), "..", 'spec_helper.rb') + +describe OpenidRegister, "index action" do + it "should get a list of all registered nodes" do + Chef::OpenIDRegistration.should_receive(:list).with(true).and_return(["one"]) + dispatch_to(OpenidRegister, :index) do |c| + c.stub!(:display) + end + end +end + +describe OpenidRegister, "show action" do + it "should raise a 404 if the nodes registration is not found" do + Chef::OpenIDRegistration.should_receive(:load).with("foo").and_raise(RuntimeError) + lambda { + dispatch_to(OpenidRegister, :show, { :id => "foo" }) + }.should raise_error(Merb::ControllerExceptions::NotFound) + end + + it "should call display on the node registration" do + Chef::OpenIDRegistration.stub!(:load).and_return(true) + dispatch_to(OpenidRegister, :show, { :id => "foo" }) do |c| + c.should_receive(:display).with(true) + end + end +end + +describe OpenidRegister, "create action" do + def do_create + dispatch_to(OpenidRegister, :create, { :id => "foo", :password => "beck" }) do |c| + c.stub!(:display) + end + end + + it "should require an id to register" do + lambda { + dispatch_to(OpenidRegister, :create, { :password => "beck" }) + }.should raise_error(Merb::ControllerExceptions::BadRequest) + end + + it "should require a password to register" do + lambda { + dispatch_to(OpenidRegister, :create, { :id => "foo" }) + }.should raise_error(Merb::ControllerExceptions::BadRequest) + end + + it "should return 400 if a node is already registered" do + Chef::OpenIDRegistration.should_receive(:has_key?).with("foo").and_return(true) + lambda { + dispatch_to(OpenidRegister, :create, { :id => "foo", :password => "beck" }) + }.should raise_error(Merb::ControllerExceptions::BadRequest) + end + + it "should store the registration in a new Chef::OpenIDRegistration" do + mock_reg = mock("Chef::OpenIDRegistration", :null_object => true) + mock_reg.should_receive(:name=).with("foo").and_return(true) + mock_reg.should_receive(:set_password).with("beck").and_return(true) + mock_reg.should_receive(:save).and_return(true) + Chef::OpenIDRegistration.stub!(:has_key?).and_return(false) + Chef::OpenIDRegistration.should_receive(:new).and_return(mock_reg) + do_create + end +end + +describe OpenidRegister, "update action" do + it "should raise a 400 error" do + lambda { + dispatch_to(OpenidRegister, :update) + } + end +end + +describe OpenidRegister, "destroy action" do + def do_destroy + dispatch_to(OpenidRegister, :destroy, { :id => "foo" }) do |c| + c.stub!(:display) + end + end + + it "should return 400 if it cannot find the registration" do + Chef::OpenIDRegistration.should_receive(:load).and_raise(ArgumentError) + lambda { + do_destroy + }.should raise_error(Merb::ControllerExceptions::BadRequest) + end + + it "should delete the registration from the store" do + mock_reg = mock("OpenIDRegistration") + mock_reg.should_receive(:destroy).and_return(true) + Chef::OpenIDRegistration.should_receive(:load).with("foo").and_return(mock_reg) + do_destroy + end +end
\ No newline at end of file diff --git a/spec/chef_server/log/merb_test.log b/spec/chef_server/log/merb_test.log new file mode 100644 index 0000000000..b2aa15df9a --- /dev/null +++ b/spec/chef_server/log/merb_test.log @@ -0,0 +1,4 @@ +Mon, 16 Jun 2008 02:08:02 GMT ~ info ~ Logfile created + ~ Not Using Sessions + ~ Not Using Sessions + ~ Not Using Sessions diff --git a/spec/chef_server/spec.opts b/spec/chef_server/spec.opts new file mode 100644 index 0000000000..3a2ff550a2 --- /dev/null +++ b/spec/chef_server/spec.opts @@ -0,0 +1,4 @@ +--color +--loadby +mtime + diff --git a/spec/chef_server/spec_helper.rb b/spec/chef_server/spec_helper.rb new file mode 100644 index 0000000000..90c1e0af7a --- /dev/null +++ b/spec/chef_server/spec_helper.rb @@ -0,0 +1,16 @@ +require 'rubygems' +require 'merb-core' +require 'spec' # Satiates Autotest and anyone else not using the Rake tasks + +Merb.start_environment( + :testing => true, + :adapter => 'runner', + :environment => ENV['MERB_ENV'] || 'test', + :init_file => File.join(File.dirname(__FILE__), "..", "..", "lib", "chef_server", "init.rb") +) + +Spec::Runner.configure do |config| + config.include(Merb::Test::ViewHelper) + config.include(Merb::Test::RouteHelper) + config.include(Merb::Test::ControllerHelper) +end diff --git a/spec/unit/compile_spec.rb b/spec/unit/compile_spec.rb index d042837606..3ae69dad2d 100644 --- a/spec/unit/compile_spec.rb +++ b/spec/unit/compile_spec.rb @@ -19,6 +19,7 @@ # require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper")) + describe Chef::Compile do before(:each) do Chef::Config.node_path(File.join(File.dirname(__FILE__), "..", "data", "compile", "nodes")) diff --git a/stories/chef-client b/stories/chef-client new file mode 100644 index 0000000000..93b8656268 --- /dev/null +++ b/stories/chef-client @@ -0,0 +1,26 @@ +Story: Applying a meal with chef-client + + As a systems administrator + I want to configure a system + So that I can drink more beer + + Scenario: The client should be rejected if the node is not verified + Given the node 'latte' + When it runs the chef-client + Then it should register with the Chef Server + + Scenario: The node registers for an OpenID + + Given the node 'latte' + When it runs the chef-client + Then it should register with the Chef Server + And CouchDB should have a 'openid_registration_latte' document + + Scenario: An administrator validates the OpenID Registration + + Given the user 'openid.hjksolutions.com/adam' + And the openid registration for 'latte' + When the user validates the registration + Then the registration validation should be true + + diff --git a/stories/chef-client.rb b/stories/chef-client.rb new file mode 100644 index 0000000000..8796559c86 --- /dev/null +++ b/stories/chef-client.rb @@ -0,0 +1,48 @@ +# +# Author:: Adam Jacob (<adam@hjksolutions.com>) +# Copyright:: Copyright (c) 2008 HJK Solutions, LLC +# License:: GNU General Public License version 2 or later +# +# This program and entire repository is free software; you can +# redistribute it and/or modify it under the terms of the GNU +# General Public License as published by the Free Software +# Foundation; either version 2 of the License, or any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +require File.expand_path(File.join(File.dirname(__FILE__), "story_helper")) + +steps_for(:chef_client) do + # Given the node 'latte' + Given("the node '$node'") do |node| + @client = Chef::Client.new + @client.build_node(node) + end + + # Given it has not registered before + Given("it has not registered before") do + Chef::FileStore.load("registration", @client.safe_name) + end + + # When it runs the chef-client + + # Then it should register with the Chef Server + + # Then CouchDB should have a 'openid_registration_latte' document + + # Then the registration validation should be 'false' + +end + +with_steps_for(:chef_client) do + create_couchdb_database + run File.join(File.dirname(__FILE__), "chef-client") +end
\ No newline at end of file diff --git a/stories/story_helper.rb b/stories/story_helper.rb new file mode 100644 index 0000000000..1c880d5a53 --- /dev/null +++ b/stories/story_helper.rb @@ -0,0 +1,33 @@ +# Author:: Adam Jacob (<adam@hjksolutions.com>) +# Copyright:: Copyright (c) 2008 HJK Solutions, LLC +# License:: GNU General Public License version 2 or later +# +# This program and entire repository is free software; you can +# redistribute it and/or modify it under the terms of the GNU +# General Public License as published by the Free Software +# Foundation; either version 2 of the License, or any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +require 'rubygems' +require 'spec/story' + +require File.join(File.dirname(__FILE__), "..", "lib", "chef") +Dir[File.join(File.dirname(__FILE__), 'lib', '**', '*.rb')].sort.each { |lib| require lib } + +Chef::Config.log_level(:fatal) +Chef::Config[:couchdb_database] = "chef_test" + +def create_couchdb_database + c = Chef::CouchDB.new + c.create_db +end + |