# # Author:: Adam Jacob () # Author:: Christopher Brown () # Author:: Nuo Yan () # Author:: Seth Falcon () # Copyright:: Copyright (c) 2008-2011 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'chef/cookbook_loader' require 'chef/cookbook_version' class Cookbooks < Application provides :html before :login_required before :params_helper attr_reader :cookbook_id def params_helper @cookbook_id = params[:id] || params[:cookbook_id] end def index @cl = fetch_cookbook_versions(6) display @cl end def show begin all_books = fetch_cookbook_versions("all", :cookbook => cookbook_id) @versions = all_books[cookbook_id].map { |v| v["version"] } if params[:cb_version] == "_latest" redirect(url(:show_specific_version_cookbook, :cookbook_id => cookbook_id, :cb_version => @versions.first)) return end @version = params[:cb_version] if !@versions.include?(@version) msg = { :warning => ["Cookbook #{cookbook_id} (#{params[:cb_version]})", "is not available in the #{session[:environment]}", "environment." ].join(" ") } redirect(url(:cookbooks), :message => msg) return end cookbook_url = "cookbooks/#{cookbook_id}/#{@version}" rest = Chef::REST.new(Chef::Config[:chef_server_url]) @cookbook = rest.get_rest(cookbook_url) raise NotFound unless @cookbook @manifest = @cookbook.manifest display @cookbook rescue => e Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}") @_message = {:error => $!} @cl = {} render :index end end # GET /cookbooks/cookbook_id # provides :json, for the javascript on the environments web form. def cb_versions provides :json use_envs = session[:environment] && !params[:ignore_environments] num_versions = params[:num_versions] || "all" all_books = fetch_cookbook_versions(num_versions, :cookbook => cookbook_id, :use_envs => use_envs) display({ cookbook_id => all_books[cookbook_id] }) end ## ------ ## Helpers ## ## TODO: move these to a cookbooks helper module ## ------ def recipe_files # node = params.has_key?('node') ? params[:node] : nil # @recipe_files = load_all_files(:recipes, node) r = Chef::REST.new(Chef::Config[:chef_server_url]) @recipe_files = r.get_rest("cookbooks/#{params[:id]}/recipes") display @recipe_files end def attribute_files r = Chef::REST.new(Chef::Config[:chef_server_url]) @recipe_files = r.get_rest("cookbooks/#{params[:id]}/attributes") display @attribute_files end def definition_files r = Chef::REST.new(Chef::Config[:chef_server_url]) @recipe_files = r.get_rest("cookbooks/#{params[:id]}/definitions") display @definition_files end def library_files r = Chef::REST.new(Chef::Config[:chef_server_url]) @recipe_files = r.get_rest("cookbooks/#{params[:id]}/libraries") display @lib_files end def more_versions_link(cookbook) link_to("+", "JavaScript:void(0);", :title => "show other versions of #{cookbook}", :data => cookbook, :class => "cookbook_version_toggle") end def all_versions_link(cookbook) link_to("show all versions...", "JavaScript:void(0);", :class => "show_all", :id => "#{cookbook}_show_all", :data => cookbook, :title => "show all versions of #{cookbook}") end def cookbook_link(version) url(:show_specific_version_cookbook, :cookbook_id => @cookbook_id, :cb_version => version) end def cookbook_parts Chef::CookbookVersion::COOKBOOK_SEGMENTS.map do |p| part = p.to_s case part when "files" [part, "plain"] else [part, "ruby"] end end.sort { |a, b| a[0] <=> b[0] } end def highlight_content(url, type) case type when "plain" show_plain_file(url) else syntax_highlight(url) end end private def fetch_cookbook_versions(num_versions, options={}) opts = { :use_envs => true, :cookbook => nil }.merge(options) url = if opts[:use_envs] env = session[:environment] || "_default" "environments/#{env}/cookbooks" else "cookbooks" end # we want to display at most 5 versions, but we ask for 6. This # tells us if we should display a 'show all' button or not. url += "/#{opts[:cookbook]}" if opts[:cookbook] url += "?num_versions=#{num_versions}" begin result = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest(url) result.inject({}) do |ans, (name, cb)| cb["versions"].each do |v| v["url"] = url(:show_specific_version_cookbook, :cookbook_id => name, :cb_version => v["version"]) end ans[name] = cb["versions"] ans end rescue => e Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}") @_message = {:error => $!} {} end end end