chef-server-webui 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +201 -0
- data/README.rdoc +135 -0
- data/Rakefile +62 -0
- data/app/controllers/application.rb +281 -0
- data/app/controllers/clients.rb +120 -0
- data/app/controllers/cookbook_attributes.rb +41 -0
- data/app/controllers/cookbook_definitions.rb +41 -0
- data/app/controllers/cookbook_files.rb +39 -0
- data/app/controllers/cookbook_libraries.rb +41 -0
- data/app/controllers/cookbook_recipes.rb +40 -0
- data/app/controllers/cookbook_templates.rb +57 -0
- data/app/controllers/cookbooks.rb +78 -0
- data/app/controllers/databag_items.rb +102 -0
- data/app/controllers/databags.rb +83 -0
- data/app/controllers/exceptions.rb +19 -0
- data/app/controllers/main.rb +7 -0
- data/app/controllers/nodes.rb +138 -0
- data/app/controllers/openid_consumer.rb +154 -0
- data/app/controllers/roles.rb +144 -0
- data/app/controllers/search.rb +62 -0
- data/app/controllers/search_entries.rb +64 -0
- data/app/controllers/status.rb +39 -0
- data/app/controllers/users.rb +186 -0
- data/app/helpers/application_helper.rb +171 -0
- data/app/helpers/cookbook_attributes_helper.rb +7 -0
- data/app/helpers/cookbook_definitions_helper.rb +8 -0
- data/app/helpers/cookbook_files_helper.rb +8 -0
- data/app/helpers/cookbook_libraries_helper.rb +7 -0
- data/app/helpers/cookbook_recipes_helper.rb +8 -0
- data/app/helpers/cookbook_templates_helper.rb +8 -0
- data/app/helpers/exceptions_helper.rb +6 -0
- data/app/helpers/global_helpers.rb +35 -0
- data/app/helpers/nodes_helper.rb +41 -0
- data/app/helpers/openid_consumer_helper.rb +8 -0
- data/app/helpers/openid_register_helper.rb +8 -0
- data/app/helpers/openid_server_helper.rb +6 -0
- data/app/helpers/openid_server_helpers.rb +29 -0
- data/app/helpers/roles_helper.rb +5 -0
- data/app/helpers/search_entries_helper.rb +8 -0
- data/app/helpers/search_helper.rb +38 -0
- data/app/helpers/status_helper.rb +26 -0
- data/app/views/clients/_form.html.haml +22 -0
- data/app/views/clients/_navigation.html.haml +9 -0
- data/app/views/clients/edit.html.haml +6 -0
- data/app/views/clients/index.html.haml +21 -0
- data/app/views/clients/new.html.haml +6 -0
- data/app/views/clients/show.html.haml +20 -0
- data/app/views/cookbooks/index.html.haml +10 -0
- data/app/views/cookbooks/show.html.haml +40 -0
- data/app/views/databag_items/_form.html.haml +14 -0
- data/app/views/databag_items/_navigation.html.haml +9 -0
- data/app/views/databag_items/edit.html.haml +6 -0
- data/app/views/databag_items/index.html.haml +0 -0
- data/app/views/databag_items/new.html.haml +6 -0
- data/app/views/databag_items/show.html.haml +9 -0
- data/app/views/databags/_form.html.haml +12 -0
- data/app/views/databags/_item_navigation.html.haml +8 -0
- data/app/views/databags/_navigation.html.haml +9 -0
- data/app/views/databags/edit.html.haml +6 -0
- data/app/views/databags/index.html.haml +19 -0
- data/app/views/databags/new.html.haml +6 -0
- data/app/views/databags/show.html.haml +19 -0
- data/app/views/exceptions/bad_request.json.erb +1 -0
- data/app/views/exceptions/internal_server_error.html.erb +216 -0
- data/app/views/exceptions/not_acceptable.html.erb +63 -0
- data/app/views/exceptions/not_found.html.erb +47 -0
- data/app/views/exceptions/standard_error.html.erb +217 -0
- data/app/views/layout/_jsonedit.html.haml +82 -0
- data/app/views/layout/chef_server_webui.html.haml +56 -0
- data/app/views/layout/login.html.haml +36 -0
- data/app/views/main/index.html.erb +1 -0
- data/app/views/nodes/_action.html.haml +13 -0
- data/app/views/nodes/_form.html.haml +53 -0
- data/app/views/nodes/_navigation.html.haml +9 -0
- data/app/views/nodes/_resource.html.haml +22 -0
- data/app/views/nodes/edit.html.haml +7 -0
- data/app/views/nodes/index.html.haml +25 -0
- data/app/views/nodes/new.html.haml +6 -0
- data/app/views/nodes/show.html.haml +60 -0
- data/app/views/openid_consumer/index.html.haml +28 -0
- data/app/views/openid_consumer/start.html.haml +4 -0
- data/app/views/openid_login/index.html.haml +5 -0
- data/app/views/openid_register/index.html.haml +19 -0
- data/app/views/openid_register/show.html.haml +7 -0
- data/app/views/roles/_form.html.haml +53 -0
- data/app/views/roles/_navigation.html.haml +9 -0
- data/app/views/roles/edit.html.haml +6 -0
- data/app/views/roles/index.html.haml +21 -0
- data/app/views/roles/new.html.haml +6 -0
- data/app/views/roles/show.html.haml +54 -0
- data/app/views/search/_search_form.html.haml +6 -0
- data/app/views/search/index.html.haml +8 -0
- data/app/views/search/show.html.haml +13 -0
- data/app/views/search_entries/index.html.haml +8 -0
- data/app/views/search_entries/show.html.haml +7 -0
- data/app/views/status/index.html.haml +90 -0
- data/app/views/users/_form.html.haml +39 -0
- data/app/views/users/_navigation.html.haml +9 -0
- data/app/views/users/edit.html.haml +6 -0
- data/app/views/users/index.html.haml +20 -0
- data/app/views/users/login.html.haml +16 -0
- data/app/views/users/new.html.haml +27 -0
- data/app/views/users/show.html.haml +13 -0
- data/app/views/users/start.html.haml +4 -0
- data/config.ru +84 -0
- data/config/init.rb +49 -0
- data/config/router.rb +6 -0
- data/lib/chef-server-webui.rb +155 -0
- data/lib/chef-server-webui/merbtasks.rb +103 -0
- data/lib/chef-server-webui/slicetasks.rb +20 -0
- data/lib/chef-server-webui/spectasks.rb +53 -0
- data/public/facebox/README.txt +4 -0
- data/public/facebox/b.png +0 -0
- data/public/facebox/bl.png +0 -0
- data/public/facebox/br.png +0 -0
- data/public/facebox/closelabel.gif +0 -0
- data/public/facebox/facebox.css +95 -0
- data/public/facebox/facebox.js +319 -0
- data/public/facebox/loading.gif +0 -0
- data/public/facebox/tl.png +0 -0
- data/public/facebox/tr.png +0 -0
- data/public/images/avatar.png +0 -0
- data/public/images/black_big.png +0 -0
- data/public/images/indicator.gif +0 -0
- data/public/images/jsonedit/add2.png +0 -0
- data/public/images/jsonedit/build-button.png +0 -0
- data/public/images/jsonedit/bullet.gif +0 -0
- data/public/images/jsonedit/bullet_orange.png +0 -0
- data/public/images/jsonedit/cross.png +0 -0
- data/public/images/jsonedit/delete.png +0 -0
- data/public/images/jsonedit/deleted.png +0 -0
- data/public/images/jsonedit/json.jpg +0 -0
- data/public/images/jsonedit/label.gif +0 -0
- data/public/images/jsonedit/minus.gif +0 -0
- data/public/images/jsonedit/pixel.gif +0 -0
- data/public/images/jsonedit/plus.gif +0 -0
- data/public/images/jsonedit/saved.png +0 -0
- data/public/images/jsonedit/table_refresh.png +0 -0
- data/public/images/jsonedit/value.gif +0 -0
- data/public/images/merb.jpg +0 -0
- data/public/images/toggle-collapse-dark.png +0 -0
- data/public/images/toggle-collapse-light.png +0 -0
- data/public/images/toggle-collapse.gif +0 -0
- data/public/images/toggle-expand-dark.png +0 -0
- data/public/images/toggle-expand-light.png +0 -0
- data/public/images/toggle-expand.gif +0 -0
- data/public/images/treeBuilderImages/Thumbs.db +0 -0
- data/public/images/treeBuilderImages/doc.gif +0 -0
- data/public/images/treeBuilderImages/docNode.gif +0 -0
- data/public/images/treeBuilderImages/docNodeLast.gif +0 -0
- data/public/images/treeBuilderImages/docNodeLastFirst.gif +0 -0
- data/public/images/treeBuilderImages/folder.gif +0 -0
- data/public/images/treeBuilderImages/folderNode.gif +0 -0
- data/public/images/treeBuilderImages/folderNodeFirst.gif +0 -0
- data/public/images/treeBuilderImages/folderNodeLast.gif +0 -0
- data/public/images/treeBuilderImages/folderNodeLastFirst.gif +0 -0
- data/public/images/treeBuilderImages/folderNodeOpen.gif +0 -0
- data/public/images/treeBuilderImages/folderNodeOpenFirst.gif +0 -0
- data/public/images/treeBuilderImages/folderNodeOpenLast.gif +0 -0
- data/public/images/treeBuilderImages/folderNodeOpenLastFirst.gif +0 -0
- data/public/images/treeBuilderImages/folderOpen.gif +0 -0
- data/public/images/treeBuilderImages/vertLine.gif +0 -0
- data/public/javascripts/chef.js +160 -0
- data/public/javascripts/jquery-1.3.2.min.js +19 -0
- data/public/javascripts/jquery-ui-1.7.1.custom.min.js +65 -0
- data/public/javascripts/jquery.editinline.js +108 -0
- data/public/javascripts/jquery.jeditable.mini.js +30 -0
- data/public/javascripts/jquery.livequery.js +250 -0
- data/public/javascripts/jquery.localscroll.js +104 -0
- data/public/javascripts/jquery.scrollTo.js +150 -0
- data/public/javascripts/jquery.tools.min.js +17 -0
- data/public/javascripts/jquery.treeTable.min.js +165 -0
- data/public/javascripts/json.js +153 -0
- data/public/javascripts/jsonedit_main.js +675 -0
- data/public/javascripts/yetii-min.js +1 -0
- data/public/stylesheets/base.css +336 -0
- data/public/stylesheets/chef.css +157 -0
- data/public/stylesheets/images/ui-bg_diagonals-small_0_aaaaaa_40x40.png +0 -0
- data/public/stylesheets/images/ui-bg_diagonals-thick_15_444444_40x40.png +0 -0
- data/public/stylesheets/images/ui-bg_glass_100_f0f0f0_1x400.png +0 -0
- data/public/stylesheets/images/ui-bg_glass_50_99c2ff_1x400.png +0 -0
- data/public/stylesheets/images/ui-bg_glass_55_fbf5d0_1x400.png +0 -0
- data/public/stylesheets/images/ui-bg_glass_80_e6e6e6_1x400.png +0 -0
- data/public/stylesheets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/public/stylesheets/images/ui-bg_highlight-hard_100_f9f9f9_1x100.png +0 -0
- data/public/stylesheets/images/ui-bg_highlight-soft_100_e7eef3_1x100.png +0 -0
- data/public/stylesheets/images/ui-icons_222222_256x240.png +0 -0
- data/public/stylesheets/images/ui-icons_2694e8_256x240.png +0 -0
- data/public/stylesheets/images/ui-icons_2e83ff_256x240.png +0 -0
- data/public/stylesheets/images/ui-icons_72a7cf_256x240.png +0 -0
- data/public/stylesheets/images/ui-icons_888888_256x240.png +0 -0
- data/public/stylesheets/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/public/stylesheets/images/ui-icons_ffffff_256x240.png +0 -0
- data/public/stylesheets/jquery-ui-1.7.1.custom.css +404 -0
- data/public/stylesheets/jquery.treeTable.css +43 -0
- data/public/stylesheets/jsonedit_main.css +280 -0
- data/public/stylesheets/themes/bec-green/style.css +290 -0
- data/public/stylesheets/themes/bec/style.css +301 -0
- data/public/stylesheets/themes/blue/style.css +280 -0
- data/public/stylesheets/themes/default/style.css +267 -0
- data/public/stylesheets/themes/djime-cerulean/style.css +298 -0
- data/public/stylesheets/themes/kathleene/style.css +272 -0
- data/public/stylesheets/themes/orange/style.css +263 -0
- data/public/stylesheets/themes/reidb-greenish/style.css +301 -0
- data/stubs/app/controllers/application.rb +2 -0
- data/stubs/app/controllers/main.rb +2 -0
- metadata +399 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Nuo Yan (<nuo@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2008 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' / 'data_bag_item'
|
|
20
|
+
|
|
21
|
+
class ChefServerWebui::DatabagItems < ChefServerWebui::Application
|
|
22
|
+
|
|
23
|
+
provides :html, :json
|
|
24
|
+
before :login_required
|
|
25
|
+
|
|
26
|
+
def edit
|
|
27
|
+
begin
|
|
28
|
+
@databag_item = Chef::DataBagItem.load(params[:databag_id], params[:id])
|
|
29
|
+
@default_data = @databag_item
|
|
30
|
+
rescue => e
|
|
31
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
32
|
+
@_message = { :error => "Could not load the databag item" }
|
|
33
|
+
end
|
|
34
|
+
render
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def update
|
|
38
|
+
begin
|
|
39
|
+
@databag_item = Chef::DataBagItem.new
|
|
40
|
+
@databag_item.data_bag params[:databag_id]
|
|
41
|
+
@databag_item.raw_data = JSON.parse(params[:json_data])
|
|
42
|
+
raise ArgumentError, "Updating id is not allowed" unless @databag_item.raw_data['id'] == params[:id] #to be consistent with other objects, changing id is not allowed.
|
|
43
|
+
@databag_item.save
|
|
44
|
+
redirect(slice_url(:databag_databag_items, :databag_id => params[:databag_id], :id => @databag_item.name), :message => { :notice => "Updated Databag Item #{@databag_item.name}" })
|
|
45
|
+
rescue => e
|
|
46
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
47
|
+
@_message = { :error => "Could not update the databag item" }
|
|
48
|
+
@databag_item = Chef::DataBagItem.load(params[:databag_id], params[:id])
|
|
49
|
+
@default_data = @databag_item
|
|
50
|
+
render :edit
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def new
|
|
55
|
+
@default_data = {'id'=>''}
|
|
56
|
+
render
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def create
|
|
60
|
+
begin
|
|
61
|
+
@databag_name = params[:databag_id]
|
|
62
|
+
@databag_item = Chef::DataBagItem.new
|
|
63
|
+
@databag_item.data_bag @databag_name
|
|
64
|
+
@databag_item.raw_data = JSON.parse(params[:json_data])
|
|
65
|
+
@databag_item.create
|
|
66
|
+
redirect(slice_url(:databag_databag_items, :databag_id => @databag_name), :message => { :notice => "Databag item created successfully" })
|
|
67
|
+
rescue => e
|
|
68
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
69
|
+
@_message = { :error => "Could not create databag item" }
|
|
70
|
+
render :new
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def index
|
|
75
|
+
render
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def show
|
|
79
|
+
begin
|
|
80
|
+
@databag_name = params[:databag_id]
|
|
81
|
+
@databag_item_name = params[:id]
|
|
82
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
83
|
+
@databag_item = r.get_rest("data/#{params[:databag_id]}/#{params[:id]}")
|
|
84
|
+
display @databag_item
|
|
85
|
+
rescue => e
|
|
86
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
87
|
+
redirect(slice_url(:databag_databag_items), {:message => { :error => "Could not show the databag item" }, :permanent => true})
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def destroy(databag_id=params[:databag_id], item_id=params[:id])
|
|
92
|
+
begin
|
|
93
|
+
@databag_item = Chef::DataBagItem.new
|
|
94
|
+
@databag_item.destroy(databag_id, item_id)
|
|
95
|
+
redirect(slice_url(:databag_databag_items), {:message => { :notice => "Databag item deleted successfully" }, :permanent => true})
|
|
96
|
+
rescue => e
|
|
97
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
98
|
+
redirect(slice_url(:databag_databag_items), {:message => { :error => "Could not delete databag item" }, :permanent => true})
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Nuo Yan (<nuo@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2008 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' / 'data_bag'
|
|
20
|
+
|
|
21
|
+
class ChefServerWebui::Databags < ChefServerWebui::Application
|
|
22
|
+
|
|
23
|
+
provides :html, :json
|
|
24
|
+
before :login_required
|
|
25
|
+
|
|
26
|
+
def new
|
|
27
|
+
@databag = Chef::DataBag.new
|
|
28
|
+
render
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def create
|
|
32
|
+
begin
|
|
33
|
+
@databag = Chef::DataBag.new
|
|
34
|
+
@databag.name params[:name]
|
|
35
|
+
@databag.create
|
|
36
|
+
redirect(slice_url(:databags), :message => { :notice => "Created Databag #{@databag.name}" })
|
|
37
|
+
rescue => e
|
|
38
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
39
|
+
@_message = { :error => "Could not create databag" }
|
|
40
|
+
render :new
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def index
|
|
45
|
+
@databags = begin
|
|
46
|
+
Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("data")
|
|
47
|
+
rescue => e
|
|
48
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
49
|
+
@_message = { :error => "Could not list databags" }
|
|
50
|
+
{}
|
|
51
|
+
end
|
|
52
|
+
render
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def show
|
|
56
|
+
begin
|
|
57
|
+
@databag_name = params[:id]
|
|
58
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
59
|
+
@databag = r.get_rest("data/#{params[:id]}")
|
|
60
|
+
raise NotFound unless @databag
|
|
61
|
+
display @databag
|
|
62
|
+
rescue => e
|
|
63
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
64
|
+
@databags = Chef::DataBag.list
|
|
65
|
+
@_message = { :error => "Could not load databag"}
|
|
66
|
+
render :index
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def destroy
|
|
71
|
+
begin
|
|
72
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
73
|
+
r.delete_rest("data/#{params[:id]}")
|
|
74
|
+
redirect(absolute_slice_url(:databags), {:message => { :notice => "Data bag #{params[:id]} deleted successfully" }, :permanent => true})
|
|
75
|
+
rescue => e
|
|
76
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
77
|
+
@databags = Chef::DataBag.list
|
|
78
|
+
@_message = { :error => "Could not delete databag"}
|
|
79
|
+
render :index
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
|
3
|
+
# Author:: Christopher Brown (<cb@opscode.com>)
|
|
4
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
|
5
|
+
# License:: Apache License, Version 2.0
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
#
|
|
19
|
+
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
|
3
|
+
# Author:: Christopher Brown (<cb@opscode.com>)
|
|
4
|
+
# Author:: Nuo Yan (<nuo@opscode.com>)
|
|
5
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
|
6
|
+
# License:: Apache License, Version 2.0
|
|
7
|
+
#
|
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
# you may not use this file except in compliance with the License.
|
|
10
|
+
# You may obtain a copy of the License at
|
|
11
|
+
#
|
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
#
|
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
# See the License for the specific language governing permissions and
|
|
18
|
+
# limitations under the License.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
require 'chef' / 'node'
|
|
22
|
+
|
|
23
|
+
class ChefServerWebui::Nodes < ChefServerWebui::Application
|
|
24
|
+
|
|
25
|
+
provides :html
|
|
26
|
+
|
|
27
|
+
before :login_required
|
|
28
|
+
before :authorized_node, :only => [ :update, :destroy ]
|
|
29
|
+
|
|
30
|
+
def index
|
|
31
|
+
@node_list = begin
|
|
32
|
+
Chef::Node.list
|
|
33
|
+
rescue => e
|
|
34
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
35
|
+
@_message = {:error => "Could not list nodes"}
|
|
36
|
+
{}
|
|
37
|
+
end
|
|
38
|
+
render
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def show
|
|
42
|
+
@node = begin
|
|
43
|
+
Chef::Node.load(params[:id])
|
|
44
|
+
rescue => e
|
|
45
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
46
|
+
@_message = {:error => "Could not load node #{params[:id]}"}
|
|
47
|
+
Chef::Node.new
|
|
48
|
+
end
|
|
49
|
+
render
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def new
|
|
53
|
+
begin
|
|
54
|
+
@node = Chef::Node.new
|
|
55
|
+
@available_recipes = get_available_recipes
|
|
56
|
+
@available_roles = Chef::Role.list.keys.sort
|
|
57
|
+
@run_list = @node.run_list
|
|
58
|
+
render
|
|
59
|
+
rescue => e
|
|
60
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
61
|
+
@node_list = Chef::Node.list()
|
|
62
|
+
@_message = {:error => "Could not load available recipes, roles, or the run list"}
|
|
63
|
+
render :index
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def edit
|
|
68
|
+
begin
|
|
69
|
+
@node = Chef::Node.load(params[:id])
|
|
70
|
+
@available_recipes = get_available_recipes
|
|
71
|
+
@available_roles = Chef::Role.list.keys.sort
|
|
72
|
+
@run_list = @node.run_list
|
|
73
|
+
render
|
|
74
|
+
rescue => e
|
|
75
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
76
|
+
@node = Chef::Node.new
|
|
77
|
+
@available_recipes = []
|
|
78
|
+
@available_roles = []
|
|
79
|
+
@run_list = []
|
|
80
|
+
@_message = {:error => "Could not load node #{params[:id]}"}
|
|
81
|
+
render
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def create
|
|
86
|
+
begin
|
|
87
|
+
@node = Chef::Node.new
|
|
88
|
+
@node.name params[:name]
|
|
89
|
+
@node.attribute = JSON.parse(params[:attributes])
|
|
90
|
+
@node.run_list.reset!(params[:for_node] ? params[:for_node] : [])
|
|
91
|
+
raise ArgumentError, "Node name cannot be blank" if (params[:name].nil? || params[:name].length==0)
|
|
92
|
+
@node.create
|
|
93
|
+
redirect(slice_url(:nodes), :message => { :notice => "Created Node #{@node.name}" })
|
|
94
|
+
rescue => e
|
|
95
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
96
|
+
@node.attribute = JSON.parse(params[:attributes])
|
|
97
|
+
@available_recipes = get_available_recipes
|
|
98
|
+
@available_roles = Chef::Role.list.keys.sort
|
|
99
|
+
@node.run_list params[:for_node]
|
|
100
|
+
@run_list = @node.run_list
|
|
101
|
+
@_message = { :error => "Exception raised creating node, #{e.message.length <= 150 ? e.message : "please check logs for details"}" }
|
|
102
|
+
render :new
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def update
|
|
107
|
+
begin
|
|
108
|
+
@node = Chef::Node.load(params[:id])
|
|
109
|
+
@node.run_list.reset!(params[:for_node] ? params[:for_node] : [])
|
|
110
|
+
@node.attribute = JSON.parse(params[:attributes])
|
|
111
|
+
@node.save
|
|
112
|
+
@_message = { :notice => "Updated Node" }
|
|
113
|
+
render :show
|
|
114
|
+
rescue => e
|
|
115
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
116
|
+
@available_recipes = get_available_recipes
|
|
117
|
+
@available_roles = Chef::Role.list.keys.sort
|
|
118
|
+
@run_list = Chef::RunList.new
|
|
119
|
+
@run_list.reset!(params[:for_node])
|
|
120
|
+
@_message = { :error => "Exception raised updating node, #{e.message.length <= 150 ? e.message : "please check logs for details"}" }
|
|
121
|
+
render :edit
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def destroy
|
|
126
|
+
begin
|
|
127
|
+
@node = Chef::Node.load(params[:id])
|
|
128
|
+
@node.destroy
|
|
129
|
+
redirect(absolute_slice_url(:nodes), {:message => { :notice => "Node #{params[:id]} deleted successfully" }, :permanent => true})
|
|
130
|
+
rescue => e
|
|
131
|
+
Chef::Log.error("#{e}\n#{e.backtrace.join("\n")}")
|
|
132
|
+
@node_list = Chef::Node.list()
|
|
133
|
+
@_message = {:error => "Could not delete the node"}
|
|
134
|
+
render :index
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
|
3
|
+
# Author:: Christopher Brown (<cb@opscode.com>)
|
|
4
|
+
# Author:: Nuo Yan (<nuo@opscode.com>)
|
|
5
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
|
6
|
+
# License:: Apache License, Version 2.0
|
|
7
|
+
#
|
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
# you may not use this file except in compliance with the License.
|
|
10
|
+
# You may obtain a copy of the License at
|
|
11
|
+
#
|
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
#
|
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
# See the License for the specific language governing permissions and
|
|
18
|
+
# limitations under the License.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
require 'pathname'
|
|
22
|
+
require 'openid'
|
|
23
|
+
require (Chef::Config[:openid_cstore_couchdb] ? 'openid-store-couchdb' : 'openid/store/filesystem')
|
|
24
|
+
|
|
25
|
+
class ChefServerWebui::OpenidConsumer < ChefServerWebui::Application
|
|
26
|
+
|
|
27
|
+
provides :html
|
|
28
|
+
|
|
29
|
+
def index
|
|
30
|
+
if request.xhr?
|
|
31
|
+
render :layout => false
|
|
32
|
+
else
|
|
33
|
+
render :layout => 'login'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def start
|
|
38
|
+
oid = params[:openid_identifier]
|
|
39
|
+
begin
|
|
40
|
+
oidreq = consumer.begin(oid)
|
|
41
|
+
rescue OpenID::OpenIDError => e
|
|
42
|
+
raise BadRequest, "Discovery failed for #{oid}: #{e}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
return_to = absolute_slice_url(:openid_consumer_complete)
|
|
46
|
+
realm = absolute_slice_url(:openid_consumer)
|
|
47
|
+
|
|
48
|
+
if oidreq.send_redirect?(realm, return_to, params[:immediate])
|
|
49
|
+
return redirect(oidreq.redirect_url(realm, return_to, params[:immediate]))
|
|
50
|
+
else
|
|
51
|
+
@form_text = oidreq.form_markup(realm, return_to, params[:immediate], {'id' => 'openid_form'})
|
|
52
|
+
render
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def login
|
|
57
|
+
if session[:user]
|
|
58
|
+
redirect(slice_url(:nodes), :message => { :warning => "You've already logged in with user #{session[:user]}" })
|
|
59
|
+
else
|
|
60
|
+
oid = params[:openid_identifier]
|
|
61
|
+
raise(Unauthorized, "Sorry, #{oid} is not an authorized OpenID.") unless is_authorized_openid_identifier?(oid, Chef::Config[:authorized_openid_identifiers])
|
|
62
|
+
raise(Unauthorized, "Sorry, #{oid} is not an authorized OpenID Provider.") unless is_authorized_openid_provider?(oid, Chef::Config[:authorized_openid_providers])
|
|
63
|
+
start
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def complete
|
|
68
|
+
# FIXME - url_for some action is not necessarily the current URL.
|
|
69
|
+
current_url = absolute_slice_url(:openid_consumer_complete)
|
|
70
|
+
parameters = params.reject{|k,v| k == "controller" || k == "action"}
|
|
71
|
+
oidresp = consumer.complete(parameters, current_url)
|
|
72
|
+
case oidresp.status
|
|
73
|
+
when OpenID::Consumer::FAILURE
|
|
74
|
+
raise BadRequest, "Verification failed: #{oidresp.message}" + (oidresp.display_identifier ? " for identifier '#{oidresp.display_identifier}'" : "")
|
|
75
|
+
when OpenID::Consumer::SUCCESS
|
|
76
|
+
#session[:openid] = oidresp.identity_url
|
|
77
|
+
# The "if" condition no longer seems need to/can be reached, so I took it out. [nuo]
|
|
78
|
+
#
|
|
79
|
+
# if oidresp.display_identifier =~ /openid\/server\/node\/(.+)$/
|
|
80
|
+
# reg_name = $1
|
|
81
|
+
# reg = Chef::OpenIDRegistration.load(reg_name)
|
|
82
|
+
# Chef::Log.error("#{reg_name} is an admin #{reg.admin}")
|
|
83
|
+
# session[:level] = reg.admin ? :admin : :node
|
|
84
|
+
# session[:node_name] = $1
|
|
85
|
+
#else
|
|
86
|
+
users = Chef::WebUIUser.list
|
|
87
|
+
#TODO: This is expensive. Should think of a better way [nuo]
|
|
88
|
+
# Go through each user object and check if the current OpenID associates with the user
|
|
89
|
+
users.each do |u, url|
|
|
90
|
+
user = Chef::WebUIUser.load(u)
|
|
91
|
+
if user.openid == oidresp.identity_url
|
|
92
|
+
session[:user] = user.name
|
|
93
|
+
session[:level] = :admin
|
|
94
|
+
break
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
if session[:user].nil?
|
|
98
|
+
redirect(slice_url(:openid_consumer), :message => { :error => "No user is associated with this OpenID." })
|
|
99
|
+
return "No user is associated with this OpenID."
|
|
100
|
+
end
|
|
101
|
+
#end
|
|
102
|
+
redirect_back_or_default(absolute_slice_url(:nodes))
|
|
103
|
+
return "Verification of #{oidresp.display_identifier} succeeded."
|
|
104
|
+
when OpenID::Consumer::SETUP_NEEDED
|
|
105
|
+
return "Immediate request failed - Setup Needed"
|
|
106
|
+
when OpenID::Consumer::CANCEL
|
|
107
|
+
return "OpenID transaction cancelled."
|
|
108
|
+
else
|
|
109
|
+
end
|
|
110
|
+
redirect absolute_slice_url(:openid_consumer)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def logout
|
|
114
|
+
cleanup_session
|
|
115
|
+
redirect slice_url(:top)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
private
|
|
119
|
+
def is_authorized_openid_provider?(openid, authorized_providers)
|
|
120
|
+
Chef::Log.debug("checking for valid openid provider: openid: #{openid}, authorized providers: #{authorized_providers}")
|
|
121
|
+
if authorized_providers and openid
|
|
122
|
+
if authorized_providers.length > 0
|
|
123
|
+
authorized_providers.detect { |p| Chef::Log.debug("openid: #{openid} (#{openid.class}), p: #{p} (#{p.class})"); openid.match(p) }
|
|
124
|
+
else
|
|
125
|
+
true
|
|
126
|
+
end
|
|
127
|
+
else
|
|
128
|
+
true
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def is_authorized_openid_identifier?(openid, authorized_identifiers)
|
|
133
|
+
Chef::Log.debug("checking for valid openid identifier: openid: #{openid}, authorized openids: #{authorized_identifiers}")
|
|
134
|
+
if authorized_identifiers and openid
|
|
135
|
+
if authorized_identifiers.length > 0
|
|
136
|
+
authorized_identifiers.detect { |p| Chef::Log.debug("openid: #{openid} (#{openid.class}), p: #{p} (#{p.class})"); openid == p }
|
|
137
|
+
else
|
|
138
|
+
true
|
|
139
|
+
end
|
|
140
|
+
else
|
|
141
|
+
true
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def consumer
|
|
146
|
+
@consumer ||= OpenID::Consumer.new(session,
|
|
147
|
+
if Chef::Config[:openid_cstore_couchdb]
|
|
148
|
+
OpenID::Store::CouchDB.new(Chef::Config[:couchdb_url])
|
|
149
|
+
else
|
|
150
|
+
OpenID::Store::Filesystem.new(Chef::Config[:openid_cstore_path])
|
|
151
|
+
end)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
end
|