chef-server-webui 0.9.18 → 0.10.0.beta.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/README.rdoc +0 -4
  2. data/Rakefile +10 -0
  3. data/app/controllers/application.rb +34 -6
  4. data/app/controllers/cookbooks.rb +125 -35
  5. data/app/controllers/environments.rb +235 -0
  6. data/app/controllers/nodes.rb +26 -19
  7. data/app/controllers/roles.rb +37 -44
  8. data/app/controllers/search.rb +13 -13
  9. data/app/helpers/application_helper.rb +34 -0
  10. data/app/views/cookbooks/_cookbook_content.html.haml +7 -0
  11. data/app/views/cookbooks/index.html.haml +22 -7
  12. data/app/views/cookbooks/show.html.haml +8 -50
  13. data/app/views/environments/_form.html.erb +91 -0
  14. data/app/views/environments/_navigation.html.haml +9 -0
  15. data/app/views/environments/_version_selector.html.erb +8 -0
  16. data/app/views/environments/edit.html.erb +17 -0
  17. data/app/views/environments/index.html.haml +26 -0
  18. data/app/views/environments/new.html.erb +17 -0
  19. data/app/views/environments/show.html.haml +31 -0
  20. data/app/views/layout/application.html.haml +22 -13
  21. data/app/views/layout/login.html.haml +2 -2
  22. data/app/views/nodes/_form.html.erb +69 -0
  23. data/app/views/nodes/index.html.haml +6 -2
  24. data/app/views/nodes/show.html.haml +4 -1
  25. data/app/views/roles/_form.html.erb +92 -0
  26. data/app/views/roles/_run_lists.html.erb +26 -0
  27. data/app/views/roles/edit.html.haml +1 -1
  28. data/app/views/roles/new.html.haml +1 -1
  29. data/app/views/roles/show.html.haml +10 -7
  30. data/app/views/status/index.html.haml +2 -1
  31. data/bin/chef-server-webui +1 -0
  32. data/config/router.rb +14 -8
  33. data/lib/chef-server-webui/version.rb +1 -1
  34. data/public/javascripts/chef.js +206 -49
  35. data/public/javascripts/cookbook_constraint_ctrl.js +191 -0
  36. data/public/javascripts/cookbook_versions.js +75 -0
  37. data/public/javascripts/jquery-1.4.4.min.js +167 -0
  38. data/public/javascripts/jquery.suggest.js +250 -0
  39. data/public/stylesheets/base.css +30 -24
  40. data/public/stylesheets/chef.css +212 -45
  41. data/public/stylesheets/jquery.suggest.css +28 -0
  42. data/public/stylesheets/jsonedit_main.css +26 -10
  43. data/public/stylesheets/themes/djime-cerulean/style.css +31 -18
  44. metadata +22 -29
  45. data/app/controllers/cookbook_attributes.rb +0 -41
  46. data/app/controllers/cookbook_definitions.rb +0 -41
  47. data/app/controllers/cookbook_files.rb +0 -39
  48. data/app/controllers/cookbook_libraries.rb +0 -41
  49. data/app/controllers/cookbook_recipes.rb +0 -40
  50. data/app/controllers/cookbook_templates.rb +0 -57
  51. data/app/helpers/cookbook_attributes_helper.rb +0 -7
  52. data/app/helpers/cookbook_definitions_helper.rb +0 -8
  53. data/app/helpers/cookbook_files_helper.rb +0 -8
  54. data/app/helpers/cookbook_libraries_helper.rb +0 -7
  55. data/app/helpers/cookbook_recipes_helper.rb +0 -8
  56. data/app/helpers/cookbook_templates_helper.rb +0 -8
  57. data/app/helpers/exceptions_helper.rb +0 -6
  58. data/app/helpers/global_helpers.rb +0 -39
  59. data/app/helpers/nodes_helper.rb +0 -43
  60. data/app/helpers/openid_consumer_helper.rb +0 -8
  61. data/app/helpers/openid_register_helper.rb +0 -8
  62. data/app/helpers/openid_server_helper.rb +0 -6
  63. data/app/helpers/openid_server_helpers.rb +0 -32
  64. data/app/helpers/roles_helper.rb +0 -5
  65. data/app/helpers/search_entries_helper.rb +0 -8
  66. data/app/helpers/search_helper.rb +0 -44
  67. data/app/views/nodes/_form.html.haml +0 -52
  68. data/app/views/roles/_form.html.haml +0 -52
data/README.rdoc CHANGED
@@ -34,8 +34,6 @@ Install these via your platform's preferred method; for example apt, yum, ports,
34
34
 
35
35
  * Git
36
36
  * CouchDB
37
- * libxml2 development package (for webrat)
38
- * libxslt develoment package (for webrat)
39
37
 
40
38
  Install the following RubyGems.
41
39
 
@@ -43,9 +41,7 @@ Install the following RubyGems.
43
41
  * rake
44
42
  * rspec
45
43
  * cucumber
46
- * webrat
47
44
  * merb-core
48
- * roman-merb_cucumber
49
45
 
50
46
  Ohai is also by Opscode and available on GitHub, http://github.com/opscode/ohai/tree/master.
51
47
 
data/Rakefile CHANGED
@@ -39,3 +39,13 @@ task :gemspec do
39
39
  end
40
40
  end
41
41
 
42
+ desc "Create a new Balsamiq Mockups project"
43
+ task :new_mockup, :name do |t, args|
44
+ if args[:name].nil?
45
+ puts "You must supply a name for your mockups project directory: `rake new_mockup[project-name]`"
46
+ exit
47
+ end
48
+ src = "mockups/base-mockup/."
49
+ dest = "mockups/#{args[:name]}"
50
+ FileUtils.cp_r src, dest
51
+ end
@@ -25,6 +25,8 @@ class Application < Merb::Controller
25
25
 
26
26
  include Chef::Mixin::Checksum
27
27
 
28
+ before :load_environments
29
+
28
30
  # Check if the user is logged in and if the user still exists
29
31
  def login_required
30
32
  if session[:user]
@@ -48,7 +50,7 @@ class Application < Merb::Controller
48
50
  end
49
51
 
50
52
  def cleanup_session
51
- [:user,:level].each { |n| session.delete(n) }
53
+ [:user,:level, :environment].each { |n| session.delete(n) }
52
54
  end
53
55
 
54
56
  def logout_and_redirect_to_login
@@ -111,6 +113,10 @@ class Application < Merb::Controller
111
113
  end
112
114
  end
113
115
 
116
+ def load_environments
117
+ @environments = Chef::Environment.list.keys.sort
118
+ end
119
+
114
120
  # Load a cookbook and return a hash with a list of all the files of a
115
121
  # given segment (attributes, recipes, definitions, libraries)
116
122
  #
@@ -169,9 +175,9 @@ class Application < Merb::Controller
169
175
  def append_tree(name, html, node, count, parent)
170
176
  to_do = node
171
177
  #to_do = node.kind_of?(Chef::Node) ? node.attribute : node
172
- Chef::Log.error("I have #{to_do.inspect}")
178
+ Chef::Log.debug("I have #{to_do.inspect}")
173
179
  to_do.sort{ |a,b| a[0] <=> b[0] }.each do |key, value|
174
- Chef::Log.error("I am #{key.inspect} #{value.inspect}")
180
+ Chef::Log.debug("I am #{key.inspect} #{value.inspect}")
175
181
  to_send = Array.new
176
182
  count += 1
177
183
  is_parent = false
@@ -253,13 +259,35 @@ class Application < Merb::Controller
253
259
  end
254
260
  end
255
261
 
256
- def get_available_recipes
257
- r = Chef::REST.new(Chef::Config[:chef_server_url])
258
- r.get_rest('cookbooks/_recipes')
262
+ def list_available_recipes_for(environment)
263
+ Chef::Environment.load_filtered_recipe_list(environment)
259
264
  end
260
265
 
261
266
  def convert_newline_to_br(string)
262
267
  string.to_s.gsub(/\n/, '<br />') unless string.nil?
263
268
  end
264
269
 
270
+ def format_exception(exception)
271
+ require 'pp'
272
+ pretty_params = StringIO.new
273
+ PP.pp({:request_params => params}, pretty_params)
274
+ "#{exception.class.name}: #{exception.message}\n#{pretty_params.string}\n#{exception.backtrace.join("\n")}"
275
+ end
276
+
277
+ def conflict?(exception)
278
+ exception.kind_of?(Net::HTTPServerException) && exception.message =~ /409/
279
+ end
280
+
281
+ def forbidden?(exception)
282
+ exception.kind_of?(Net::HTTPServerException) && exception.message =~ /403/
283
+ end
284
+
285
+ def not_found?(exception)
286
+ exception.kind_of?(Net::HTTPServerException) && exception.message =~ /404/
287
+ end
288
+
289
+ def bad_request?(exception)
290
+ exception.kind_of?(Net::HTTPServerException) && exception.message =~ /400/
291
+ end
292
+
265
293
  end
@@ -2,15 +2,16 @@
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
3
  # Author:: Christopher Brown (<cb@opscode.com>)
4
4
  # Author:: Nuo Yan (<nuo@opscode.com>)
5
- # Copyright:: Copyright (c) 2008 Opscode, Inc.
5
+ # Author:: Seth Falcon (<seth@opscode.com>)
6
+ # Copyright:: Copyright (c) 2008-2011 Opscode, Inc.
6
7
  # License:: Apache License, Version 2.0
7
8
  #
8
9
  # Licensed under the Apache License, Version 2.0 (the "License");
9
10
  # you may not use this file except in compliance with the License.
10
11
  # You may obtain a copy of the License at
11
- #
12
+ #
12
13
  # http://www.apache.org/licenses/LICENSE-2.0
13
- #
14
+ #
14
15
  # Unless required by applicable law or agreed to in writing, software
15
16
  # distributed under the License is distributed on an "AS IS" BASIS,
16
17
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,44 +23,44 @@ require 'chef/cookbook_loader'
22
23
  require 'chef/cookbook_version'
23
24
 
24
25
  class Cookbooks < Application
25
-
26
+
26
27
  provides :html
27
28
  before :login_required
28
29
  before :params_helper
29
-
30
+
30
31
  attr_reader :cookbook_id
31
32
  def params_helper
32
33
  @cookbook_id = params[:id] || params[:cookbook_id]
33
34
  end
34
-
35
+
35
36
  def index
36
- @cl = begin
37
- Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("cookbooks")
38
- rescue => e
39
- Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
40
- @_message = {:error => $!}
41
- {}
42
- end
43
- render
37
+ @cl = fetch_cookbook_versions(6)
38
+ display @cl
44
39
  end
45
40
 
46
41
  def show
47
42
  begin
48
- # array of versions, sorted from large to small e.g. ["0.20.0", "0.1.0"]
49
- versions = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("cookbooks/#{cookbook_id}")[cookbook_id].sort!{|x,y| y <=> x }
50
- # if version is not specified in the url, get the most recent version, otherwise get the specified version
51
- version = if params[:cb_version].nil? || params[:cb_version].empty?
52
- versions.first
53
- else
54
- params[:cb_version]
55
- end
56
-
57
- @cookbook = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("cookbooks/#{cookbook_id}/#{version}")
58
-
59
- # by default always show the largest version number (assuming largest means most recent)
60
- @other_versions = versions - [version]
43
+ all_books = fetch_cookbook_versions("all", :cookbook => cookbook_id)
44
+ @versions = all_books[cookbook_id].map { |v| v["version"] }
45
+ if params[:cb_version] == "_latest"
46
+ redirect(url(:show_specific_version_cookbook,
47
+ :cookbook_id => cookbook_id,
48
+ :cb_version => @versions.first))
49
+ return
50
+ end
51
+ @version = params[:cb_version]
52
+ if !@versions.include?(@version)
53
+ msg = { :warning => ["Cookbook #{cookbook_id} (#{params[:cb_version]})",
54
+ "is not available in the #{session[:environment]}",
55
+ "environment."
56
+ ].join(" ") }
57
+ redirect(url(:cookbooks), :message => msg)
58
+ return
59
+ end
60
+ cookbook_url = "cookbooks/#{cookbook_id}/#{@version}"
61
+ rest = Chef::REST.new(Chef::Config[:chef_server_url])
62
+ @cookbook = rest.get_rest(cookbook_url)
61
63
  raise NotFound unless @cookbook
62
-
63
64
  @manifest = @cookbook.manifest
64
65
  display @cookbook
65
66
  rescue => e
@@ -67,14 +68,31 @@ class Cookbooks < Application
67
68
  @_message = {:error => $!}
68
69
  @cl = {}
69
70
  render :index
70
- end
71
+ end
72
+ end
73
+
74
+ # GET /cookbooks/cookbook_id
75
+ # provides :json, for the javascript on the environments web form.
76
+ def cb_versions
77
+ provides :json
78
+ use_envs = session[:environment] && !params[:ignore_environments]
79
+ num_versions = params[:num_versions] || "all"
80
+ all_books = fetch_cookbook_versions(num_versions, :cookbook => cookbook_id,
81
+ :use_envs => use_envs)
82
+ display({ cookbook_id => all_books[cookbook_id] })
71
83
  end
72
-
84
+
85
+ ## ------
86
+ ## Helpers
87
+ ##
88
+ ## TODO: move these to a cookbooks helper module
89
+ ## ------
90
+
73
91
  def recipe_files
74
- # node = params.has_key?('node') ? params[:node] : nil
92
+ # node = params.has_key?('node') ? params[:node] : nil
75
93
  # @recipe_files = load_all_files(:recipes, node)
76
94
  r = Chef::REST.new(Chef::Config[:chef_server_url])
77
- @recipe_files = r.get_rest("cookbooks/#{params[:id]}/recipes")
95
+ @recipe_files = r.get_rest("cookbooks/#{params[:id]}/recipes")
78
96
  display @recipe_files
79
97
  end
80
98
 
@@ -83,17 +101,89 @@ class Cookbooks < Application
83
101
  @recipe_files = r.get_rest("cookbooks/#{params[:id]}/attributes")
84
102
  display @attribute_files
85
103
  end
86
-
104
+
87
105
  def definition_files
88
106
  r = Chef::REST.new(Chef::Config[:chef_server_url])
89
107
  @recipe_files = r.get_rest("cookbooks/#{params[:id]}/definitions")
90
108
  display @definition_files
91
109
  end
92
-
110
+
93
111
  def library_files
94
112
  r = Chef::REST.new(Chef::Config[:chef_server_url])
95
113
  @recipe_files = r.get_rest("cookbooks/#{params[:id]}/libraries")
96
114
  display @lib_files
97
115
  end
98
-
116
+
117
+ def more_versions_link(cookbook)
118
+ link_to("+", "JavaScript:void(0);",
119
+ :title => "show other versions of #{cookbook}",
120
+ :data => cookbook,
121
+ :class => "cookbook_version_toggle")
122
+ end
123
+
124
+ def all_versions_link(cookbook)
125
+ link_to("show all versions...", "JavaScript:void(0);",
126
+ :class => "show_all",
127
+ :id => "#{cookbook}_show_all",
128
+ :data => cookbook,
129
+ :title => "show all versions of #{cookbook}")
130
+ end
131
+
132
+ def cookbook_link(version)
133
+ url(:show_specific_version_cookbook,
134
+ :cookbook_id => @cookbook_id, :cb_version => version)
135
+ end
136
+
137
+ def cookbook_parts
138
+ Chef::CookbookVersion::COOKBOOK_SEGMENTS.map do |p|
139
+ part = p.to_s
140
+ case part
141
+ when "files"
142
+ [part, "plain"]
143
+ else
144
+ [part, "ruby"]
145
+ end
146
+ end.sort { |a, b| a[0] <=> b[0] }
147
+ end
148
+
149
+ def highlight_content(url, type)
150
+ case type
151
+ when "plain"
152
+ show_plain_file(url)
153
+ else
154
+ syntax_highlight(url)
155
+ end
156
+ end
157
+
158
+ private
159
+
160
+ def fetch_cookbook_versions(num_versions, options={})
161
+ opts = { :use_envs => true, :cookbook => nil }.merge(options)
162
+ url = if opts[:use_envs]
163
+ env = session[:environment] || "_default"
164
+ "environments/#{env}/cookbooks"
165
+ else
166
+ "cookbooks"
167
+ end
168
+ # we want to display at most 5 versions, but we ask for 6. This
169
+ # tells us if we should display a 'show all' button or not.
170
+ url += "/#{opts[:cookbook]}" if opts[:cookbook]
171
+ url += "?num_versions=#{num_versions}"
172
+ begin
173
+ result = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest(url)
174
+ result.inject({}) do |ans, (name, cb)|
175
+ cb["versions"].each do |v|
176
+ v["url"] = url(:show_specific_version_cookbook, :cookbook_id => name,
177
+ :cb_version => v["version"])
178
+ end
179
+ ans[name] = cb["versions"]
180
+ ans
181
+ end
182
+ rescue => e
183
+ Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
184
+ @_message = {:error => $!}
185
+ {}
186
+ end
187
+ end
188
+
99
189
  end
@@ -0,0 +1,235 @@
1
+ #
2
+ # Author:: Stephen Delano (<stephen@opscode.com>)
3
+ # Copyright:: Copyright (c) 2010 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/environment'
20
+
21
+ class Environments < Application
22
+
23
+ provides :html
24
+ before :login_required
25
+ before :require_admin, :only => [:create, :update, :destroy]
26
+
27
+ # GET /environments
28
+ def index
29
+ @environment_list = begin
30
+ Chef::Environment.list
31
+ rescue => e
32
+ Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
33
+ @_message = "Could not list environments"
34
+ {}
35
+ end
36
+ render
37
+ end
38
+
39
+ # GET /environments/:id
40
+ def show
41
+ load_environment
42
+ render
43
+ end
44
+
45
+ # GET /environemnts/new
46
+ def new
47
+ @environment = Chef::Environment.new
48
+ load_cookbooks
49
+ render :new
50
+ end
51
+
52
+ # POST /environments
53
+ def create
54
+ @environment = Chef::Environment.new
55
+ if @environment.update_from_params(processed_params=process_params)
56
+ begin
57
+ @environment.create
58
+ redirect(url(:environments), :message => { :notice => "Created Environment #{@environment.name}" })
59
+ rescue Net::HTTPServerException => e
60
+ if conflict?(e)
61
+ Chef::Log.debug("Got 409 conflict creating environment #{params[:name]}\n#{format_exception(e)}")
62
+ redirect(url(:new_environment), :message => { :error => "An environment with that name already exists"})
63
+ elsif forbidden?(e)
64
+ # Currently it's not possible to get 403 here. I leave the code here for completeness and may be useful in the future.[nuo]
65
+ Chef::Log.debug("Got 403 forbidden creating environment #{params[:name]}\n#{format_exception(e)}")
66
+ redirect(url(:new_environment), :message => { :error => "Permission Denied. You do not have permission to create an environment."})
67
+ else
68
+ Chef::Log.error("Error communicating with the API server\n#{format_exception(e)}")
69
+ raise
70
+ end
71
+ end
72
+ else
73
+ load_cookbooks
74
+ # By rendering :new, the view shows errors from @environment.invalid_fields
75
+ render :new
76
+ end
77
+ end
78
+
79
+ # GET /environments/:id/edit
80
+ def edit
81
+ load_environment
82
+ if @environment.name == "_default"
83
+ msg = { :warning => "The '_default' environment cannot be edited." }
84
+ redirect(url(:environments), :message => msg)
85
+ return
86
+ end
87
+ load_cookbooks
88
+ render
89
+ end
90
+
91
+ # PUT /environments/:id
92
+ def update
93
+ load_environment
94
+ if @environment.update_from_params(process_params(params[:id]))
95
+ begin
96
+ @environment.save
97
+ redirect(url(:environment, @environment.name), :message => { :notice => "Updated Environment #{@environment.name}" })
98
+ rescue Net::HTTPServerException => e
99
+ if forbidden?(e)
100
+ # Currently it's not possible to get 403 here. I leave the code here for completeness and may be useful in the future.[nuo]
101
+ Chef::Log.debug("Got 403 forbidden updating environment #{params[:name]}\n#{format_exception(e)}")
102
+ redirect(url(:edit_environment), :message => { :error => "Permission Denied. You do not have permission to update an environment."})
103
+ else
104
+ Chef::Log.error("Error communicating with the API server\n#{format_exception(e)}")
105
+ raise
106
+ end
107
+ end
108
+ else
109
+ load_cookbooks
110
+ # By rendering :new, the view shows errors from @environment.invalid_fields
111
+ render :edit
112
+ end
113
+ end
114
+
115
+ # DELETE /environments/:id
116
+ def destroy
117
+ begin
118
+ @environment = Chef::Environment.load(params[:id])
119
+ @environment.destroy
120
+ redirect(absolute_url(:environments), :message => { :notice => "Environment #{@environment.name} deleted successfully." }, :permanent => true)
121
+ rescue => e
122
+ Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
123
+ @environment_list = Chef::Environment.list()
124
+ @_message = {:error => "Could not delete environment #{params[:id]}: #{e.message}"}
125
+ render :index
126
+ end
127
+ end
128
+
129
+ # GET /environments/:environment_id/cookbooks
130
+ def list_cookbooks
131
+ # TODO: rescue loading the environment
132
+ @environment = Chef::Environment.load(params[:environment_id])
133
+ @cookbooks = begin
134
+ r = Chef::REST.new(Chef::Config[:chef_server_url])
135
+ r.get_rest("/environments/#{params[:environment_id]}/cookbooks").inject({}) do |res, (cookbook, url)|
136
+ # we just want the cookbook name and the version
137
+ res[cookbook] = url.split('/').last
138
+ res
139
+ end
140
+ rescue => e
141
+ Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
142
+ @_message = "Could not load cookbooks for environment #{params[:environment_id]}"
143
+ {}
144
+ end
145
+ render
146
+ end
147
+
148
+ # GET /environments/:environment_id/nodes
149
+ def list_nodes
150
+ # TODO: rescue loading the environment
151
+ @environment = Chef::Environment.load(params[:environment_id])
152
+ @nodes = begin
153
+ r = Chef::REST.new(Chef::Config[:chef_server_url])
154
+ r.get_rest("/environments/#{params[:environment_id]}/nodes").keys.sort
155
+ rescue => e
156
+ Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
157
+ @_message = "Could not load nodes for environment #{params[:environment_id]}"
158
+ []
159
+ end
160
+ render
161
+ end
162
+
163
+ # GET /environments/:environment/recipes
164
+ def list_recipes
165
+ provides :json
166
+ display(:recipes => list_available_recipes_for(params[:environment_id]))
167
+ end
168
+
169
+ # GET /environments/:environment_id/set
170
+ def select_environment
171
+ name = params[:environment_id]
172
+ referer = request.referer || "/nodes"
173
+ if name == '_none'
174
+ session[:environment] = nil
175
+ else
176
+ # TODO: check if environment exists
177
+ session[:environment] = name
178
+ end
179
+ redirect referer
180
+ end
181
+
182
+ private
183
+
184
+ def load_environment
185
+ @environment = begin
186
+ Chef::Environment.load(params[:id])
187
+ rescue Net::HTTPServerException => e
188
+ Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
189
+ @_message = "Could not load environment #{params[:id]}"
190
+ @environment = Chef::Environment.new
191
+ false
192
+ end
193
+ end
194
+
195
+ def load_cookbooks
196
+ begin
197
+ # @cookbooks is a hash, keys are cookbook names, values are their URIs.
198
+ @cookbooks = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("cookbooks").keys.sort
199
+ rescue Net::HTTPServerException => e
200
+ Chef::Log.error(format_exception(e))
201
+ redirect(url(:new_environment), :message => { :error => "Could not load the list of available cookbooks."})
202
+ end
203
+ end
204
+
205
+ def process_params(name=params[:name])
206
+ {:name => name, :description => params[:description], :attributes => params[:attributes], :cookbook_version => search_params_for_cookbook_version_constraints}
207
+ end
208
+
209
+ def search_params_for_cookbook_version_constraints
210
+ cookbook_version_constraints = {}
211
+ index = 0
212
+ params.each do |k,v|
213
+ cookbook_name_box_id = k[/cookbook_name_(\d+)/, 1]
214
+ unless cookbook_name_box_id.nil? || v.nil? || v.empty?
215
+ cookbook_version_constraints[index] = v + " " + params["operator_#{cookbook_name_box_id}"] + " " + params["cookbook_version_#{cookbook_name_box_id}"].strip # e.g. {"0" => "foo > 0.3.0"}
216
+ index = index + 1
217
+ end
218
+ end
219
+ Chef::Log.debug("cookbook version constraints are: #{cookbook_version_constraints.inspect}")
220
+ cookbook_version_constraints
221
+ end
222
+
223
+ def cookbook_version_constraints
224
+ @environment.cookbook_versions.inject({}) do |ans, (cb, vc)|
225
+ op, version = vc.split(" ")
226
+ ans[cb] = { "version" => version, "op" => op }
227
+ ans
228
+ end
229
+ end
230
+
231
+ def constraint_operators
232
+ %w(~> >= > = < <=)
233
+ end
234
+
235
+ end