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.
- data/README.rdoc +0 -4
- data/Rakefile +10 -0
- data/app/controllers/application.rb +34 -6
- data/app/controllers/cookbooks.rb +125 -35
- data/app/controllers/environments.rb +235 -0
- data/app/controllers/nodes.rb +26 -19
- data/app/controllers/roles.rb +37 -44
- data/app/controllers/search.rb +13 -13
- data/app/helpers/application_helper.rb +34 -0
- data/app/views/cookbooks/_cookbook_content.html.haml +7 -0
- data/app/views/cookbooks/index.html.haml +22 -7
- data/app/views/cookbooks/show.html.haml +8 -50
- data/app/views/environments/_form.html.erb +91 -0
- data/app/views/environments/_navigation.html.haml +9 -0
- data/app/views/environments/_version_selector.html.erb +8 -0
- data/app/views/environments/edit.html.erb +17 -0
- data/app/views/environments/index.html.haml +26 -0
- data/app/views/environments/new.html.erb +17 -0
- data/app/views/environments/show.html.haml +31 -0
- data/app/views/layout/application.html.haml +22 -13
- data/app/views/layout/login.html.haml +2 -2
- data/app/views/nodes/_form.html.erb +69 -0
- data/app/views/nodes/index.html.haml +6 -2
- data/app/views/nodes/show.html.haml +4 -1
- data/app/views/roles/_form.html.erb +92 -0
- data/app/views/roles/_run_lists.html.erb +26 -0
- data/app/views/roles/edit.html.haml +1 -1
- data/app/views/roles/new.html.haml +1 -1
- data/app/views/roles/show.html.haml +10 -7
- data/app/views/status/index.html.haml +2 -1
- data/bin/chef-server-webui +1 -0
- data/config/router.rb +14 -8
- data/lib/chef-server-webui/version.rb +1 -1
- data/public/javascripts/chef.js +206 -49
- data/public/javascripts/cookbook_constraint_ctrl.js +191 -0
- data/public/javascripts/cookbook_versions.js +75 -0
- data/public/javascripts/jquery-1.4.4.min.js +167 -0
- data/public/javascripts/jquery.suggest.js +250 -0
- data/public/stylesheets/base.css +30 -24
- data/public/stylesheets/chef.css +212 -45
- data/public/stylesheets/jquery.suggest.css +28 -0
- data/public/stylesheets/jsonedit_main.css +26 -10
- data/public/stylesheets/themes/djime-cerulean/style.css +31 -18
- metadata +22 -29
- data/app/controllers/cookbook_attributes.rb +0 -41
- data/app/controllers/cookbook_definitions.rb +0 -41
- data/app/controllers/cookbook_files.rb +0 -39
- data/app/controllers/cookbook_libraries.rb +0 -41
- data/app/controllers/cookbook_recipes.rb +0 -40
- data/app/controllers/cookbook_templates.rb +0 -57
- data/app/helpers/cookbook_attributes_helper.rb +0 -7
- data/app/helpers/cookbook_definitions_helper.rb +0 -8
- data/app/helpers/cookbook_files_helper.rb +0 -8
- data/app/helpers/cookbook_libraries_helper.rb +0 -7
- data/app/helpers/cookbook_recipes_helper.rb +0 -8
- data/app/helpers/cookbook_templates_helper.rb +0 -8
- data/app/helpers/exceptions_helper.rb +0 -6
- data/app/helpers/global_helpers.rb +0 -39
- data/app/helpers/nodes_helper.rb +0 -43
- data/app/helpers/openid_consumer_helper.rb +0 -8
- data/app/helpers/openid_register_helper.rb +0 -8
- data/app/helpers/openid_server_helper.rb +0 -6
- data/app/helpers/openid_server_helpers.rb +0 -32
- data/app/helpers/roles_helper.rb +0 -5
- data/app/helpers/search_entries_helper.rb +0 -8
- data/app/helpers/search_helper.rb +0 -44
- data/app/views/nodes/_form.html.haml +0 -52
- 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.
|
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.
|
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
|
257
|
-
|
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
|
-
#
|
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 =
|
37
|
-
|
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
|
-
|
49
|
-
versions =
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|