runa-chef 0.8.0.1
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 +136 -0
- data/bin/chef-client +26 -0
- data/bin/chef-solo +26 -0
- data/bin/knife +27 -0
- data/bin/shef +45 -0
- data/distro/README +2 -0
- data/distro/common/man/man1/chef-indexer.1 +42 -0
- data/distro/common/man/man1/chef-server.1 +108 -0
- data/distro/common/man/man8/chef-client.8 +61 -0
- data/distro/common/man/man8/chef-solo.8 +58 -0
- data/distro/common/man/man8/knife.8 +359 -0
- data/distro/debian/etc/init.d/chef-client +175 -0
- data/distro/debian/etc/init.d/chef-indexer +175 -0
- data/distro/debian/etc/init.d/chef-server +120 -0
- data/distro/redhat/etc/init.d/chef-client +78 -0
- data/distro/redhat/etc/init.d/chef-indexer +76 -0
- data/distro/redhat/etc/init.d/chef-server +78 -0
- data/distro/redhat/etc/sysconfig/chef-client +10 -0
- data/distro/redhat/etc/sysconfig/chef-indexer +8 -0
- data/distro/redhat/etc/sysconfig/chef-server +10 -0
- data/distro/suse/etc/init.d/chef-client +121 -0
- data/lib/chef.rb +49 -0
- data/lib/chef/api_client.rb +269 -0
- data/lib/chef/application.rb +98 -0
- data/lib/chef/application/agent.rb +18 -0
- data/lib/chef/application/client.rb +214 -0
- data/lib/chef/application/knife.rb +138 -0
- data/lib/chef/application/server.rb +19 -0
- data/lib/chef/application/solo.rb +214 -0
- data/lib/chef/cache.rb +61 -0
- data/lib/chef/cache/checksum.rb +70 -0
- data/lib/chef/certificate.rb +154 -0
- data/lib/chef/client.rb +323 -0
- data/lib/chef/compile.rb +158 -0
- data/lib/chef/config.rb +195 -0
- data/lib/chef/cookbook.rb +198 -0
- data/lib/chef/cookbook/metadata.rb +487 -0
- data/lib/chef/cookbook/metadata/version.rb +87 -0
- data/lib/chef/cookbook_loader.rb +180 -0
- data/lib/chef/couchdb.rb +273 -0
- data/lib/chef/daemon.rb +170 -0
- data/lib/chef/data_bag.rb +216 -0
- data/lib/chef/data_bag_item.rb +227 -0
- data/lib/chef/exceptions.rb +39 -0
- data/lib/chef/file_cache.rb +205 -0
- data/lib/chef/knife.rb +300 -0
- data/lib/chef/knife/client_bulk_delete.rb +41 -0
- data/lib/chef/knife/client_create.rb +55 -0
- data/lib/chef/knife/client_delete.rb +37 -0
- data/lib/chef/knife/client_edit.rb +37 -0
- data/lib/chef/knife/client_list.rb +40 -0
- data/lib/chef/knife/client_reregister.rb +48 -0
- data/lib/chef/knife/client_show.rb +42 -0
- data/lib/chef/knife/configure.rb +84 -0
- data/lib/chef/knife/cookbook_bulk_delete.rb +47 -0
- data/lib/chef/knife/cookbook_delete.rb +41 -0
- data/lib/chef/knife/cookbook_download.rb +57 -0
- data/lib/chef/knife/cookbook_list.rb +41 -0
- data/lib/chef/knife/cookbook_metadata.rb +87 -0
- data/lib/chef/knife/cookbook_show.rb +75 -0
- data/lib/chef/knife/cookbook_upload.rb +173 -0
- data/lib/chef/knife/data_bag_create.rb +43 -0
- data/lib/chef/knife/data_bag_delete.rb +43 -0
- data/lib/chef/knife/data_bag_edit.rb +49 -0
- data/lib/chef/knife/data_bag_list.rb +42 -0
- data/lib/chef/knife/data_bag_show.rb +40 -0
- data/lib/chef/knife/ec2_instance_data.rb +46 -0
- data/lib/chef/knife/node_bulk_delete.rb +44 -0
- data/lib/chef/knife/node_create.rb +39 -0
- data/lib/chef/knife/node_delete.rb +36 -0
- data/lib/chef/knife/node_edit.rb +36 -0
- data/lib/chef/knife/node_from_file.rb +42 -0
- data/lib/chef/knife/node_list.rb +41 -0
- data/lib/chef/knife/node_run_list_add.rb +64 -0
- data/lib/chef/knife/node_run_list_remove.rb +45 -0
- data/lib/chef/knife/node_show.rb +46 -0
- data/lib/chef/knife/role_bulk_delete.rb +45 -0
- data/lib/chef/knife/role_create.rb +44 -0
- data/lib/chef/knife/role_delete.rb +36 -0
- data/lib/chef/knife/role_edit.rb +37 -0
- data/lib/chef/knife/role_from_file.rb +46 -0
- data/lib/chef/knife/role_list.rb +40 -0
- data/lib/chef/knife/role_show.rb +43 -0
- data/lib/chef/knife/search.rb +94 -0
- data/lib/chef/log.rb +39 -0
- data/lib/chef/mixin/check_helper.rb +31 -0
- data/lib/chef/mixin/checksum.rb +32 -0
- data/lib/chef/mixin/command.rb +390 -0
- data/lib/chef/mixin/convert_to_class_name.rb +57 -0
- data/lib/chef/mixin/create_path.rb +56 -0
- data/lib/chef/mixin/deep_merge.rb +33 -0
- data/lib/chef/mixin/find_preferred_file.rb +92 -0
- data/lib/chef/mixin/from_file.rb +50 -0
- data/lib/chef/mixin/generate_url.rb +58 -0
- data/lib/chef/mixin/language.rb +107 -0
- data/lib/chef/mixin/language_include_attribute.rb +56 -0
- data/lib/chef/mixin/language_include_recipe.rb +53 -0
- data/lib/chef/mixin/params_validate.rb +197 -0
- data/lib/chef/mixin/recipe_definition_dsl_core.rb +79 -0
- data/lib/chef/mixin/template.rb +94 -0
- data/lib/chef/nanite.rb +100 -0
- data/lib/chef/node.rb +463 -0
- data/lib/chef/node/attribute.rb +412 -0
- data/lib/chef/openid_registration.rb +181 -0
- data/lib/chef/platform.rb +268 -0
- data/lib/chef/provider.rb +101 -0
- data/lib/chef/provider/breakpoint.rb +36 -0
- data/lib/chef/provider/cron.rb +184 -0
- data/lib/chef/provider/deploy.rb +314 -0
- data/lib/chef/provider/deploy/revision.rb +70 -0
- data/lib/chef/provider/deploy/timestamped.rb +33 -0
- data/lib/chef/provider/directory.rb +72 -0
- data/lib/chef/provider/erl_call.rb +72 -0
- data/lib/chef/provider/execute.rb +58 -0
- data/lib/chef/provider/file.rb +195 -0
- data/lib/chef/provider/git.rb +203 -0
- data/lib/chef/provider/group.rb +120 -0
- data/lib/chef/provider/group/dscl.rb +128 -0
- data/lib/chef/provider/group/gpasswd.rb +50 -0
- data/lib/chef/provider/group/groupadd.rb +78 -0
- data/lib/chef/provider/group/pw.rb +88 -0
- data/lib/chef/provider/group/usermod.rb +57 -0
- data/lib/chef/provider/http_request.rb +106 -0
- data/lib/chef/provider/ifconfig.rb +131 -0
- data/lib/chef/provider/link.rb +157 -0
- data/lib/chef/provider/mdadm.rb +88 -0
- data/lib/chef/provider/mount.rb +117 -0
- data/lib/chef/provider/mount/mount.rb +208 -0
- data/lib/chef/provider/package.rb +160 -0
- data/lib/chef/provider/package/apt.rb +110 -0
- data/lib/chef/provider/package/dpkg.rb +109 -0
- data/lib/chef/provider/package/easy_install.rb +106 -0
- data/lib/chef/provider/package/freebsd.rb +153 -0
- data/lib/chef/provider/package/macports.rb +105 -0
- data/lib/chef/provider/package/portage.rb +124 -0
- data/lib/chef/provider/package/rpm.rb +99 -0
- data/lib/chef/provider/package/rubygems.rb +136 -0
- data/lib/chef/provider/package/yum-dump.py +125 -0
- data/lib/chef/provider/package/yum.rb +175 -0
- data/lib/chef/provider/package/zypper.rb +132 -0
- data/lib/chef/provider/remote_directory.rb +126 -0
- data/lib/chef/provider/remote_file.rb +141 -0
- data/lib/chef/provider/route.rb +118 -0
- data/lib/chef/provider/ruby_block.rb +33 -0
- data/lib/chef/provider/script.rb +42 -0
- data/lib/chef/provider/service.rb +135 -0
- data/lib/chef/provider/service/debian.rb +64 -0
- data/lib/chef/provider/service/freebsd.rb +156 -0
- data/lib/chef/provider/service/gentoo.rb +54 -0
- data/lib/chef/provider/service/init.rb +71 -0
- data/lib/chef/provider/service/redhat.rb +62 -0
- data/lib/chef/provider/service/simple.rb +114 -0
- data/lib/chef/provider/subversion.rb +156 -0
- data/lib/chef/provider/template.rb +175 -0
- data/lib/chef/provider/user.rb +170 -0
- data/lib/chef/provider/user/dscl.rb +280 -0
- data/lib/chef/provider/user/pw.rb +113 -0
- data/lib/chef/provider/user/useradd.rb +108 -0
- data/lib/chef/recipe.rb +105 -0
- data/lib/chef/resource.rb +380 -0
- data/lib/chef/resource/apt_package.rb +34 -0
- data/lib/chef/resource/bash.rb +33 -0
- data/lib/chef/resource/breakpoint.rb +35 -0
- data/lib/chef/resource/cron.rb +179 -0
- data/lib/chef/resource/csh.rb +33 -0
- data/lib/chef/resource/deploy.rb +359 -0
- data/lib/chef/resource/deploy_revision.rb +35 -0
- data/lib/chef/resource/directory.rb +76 -0
- data/lib/chef/resource/dpkg_package.rb +34 -0
- data/lib/chef/resource/easy_install_package.rb +41 -0
- data/lib/chef/resource/erl_call.rb +83 -0
- data/lib/chef/resource/execute.rb +127 -0
- data/lib/chef/resource/file.rb +84 -0
- data/lib/chef/resource/gem_package.rb +41 -0
- data/lib/chef/resource/git.rb +36 -0
- data/lib/chef/resource/group.rb +70 -0
- data/lib/chef/resource/http_request.rb +52 -0
- data/lib/chef/resource/ifconfig.rb +134 -0
- data/lib/chef/resource/link.rb +78 -0
- data/lib/chef/resource/macports_package.rb +29 -0
- data/lib/chef/resource/mdadm.rb +82 -0
- data/lib/chef/resource/mount.rb +135 -0
- data/lib/chef/resource/package.rb +80 -0
- data/lib/chef/resource/perl.rb +33 -0
- data/lib/chef/resource/portage_package.rb +33 -0
- data/lib/chef/resource/python.rb +33 -0
- data/lib/chef/resource/remote_directory.rb +91 -0
- data/lib/chef/resource/remote_file.rb +60 -0
- data/lib/chef/resource/route.rb +135 -0
- data/lib/chef/resource/ruby.rb +33 -0
- data/lib/chef/resource/ruby_block.rb +39 -0
- data/lib/chef/resource/scm.rb +137 -0
- data/lib/chef/resource/script.rb +51 -0
- data/lib/chef/resource/service.rb +134 -0
- data/lib/chef/resource/subversion.rb +34 -0
- data/lib/chef/resource/template.rb +60 -0
- data/lib/chef/resource/timestamped_deploy.rb +31 -0
- data/lib/chef/resource/user.rb +101 -0
- data/lib/chef/resource_collection.rb +212 -0
- data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
- data/lib/chef/resource_definition.rb +67 -0
- data/lib/chef/rest.rb +298 -0
- data/lib/chef/role.rb +301 -0
- data/lib/chef/run_list.rb +164 -0
- data/lib/chef/runner.rb +130 -0
- data/lib/chef/search/query.rb +71 -0
- data/lib/chef/shef.rb +220 -0
- data/lib/chef/shef/ext.rb +297 -0
- data/lib/chef/shef/shef_session.rb +175 -0
- data/lib/chef/streaming_cookbook_uploader.rb +185 -0
- data/lib/chef/tasks/chef_repo.rake +245 -0
- data/lib/chef/util/file_edit.rb +125 -0
- data/lib/chef/util/fileedit.rb +121 -0
- data/lib/chef/webui_user.rb +231 -0
- metadata +398 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Nuo Yan (<nuo@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2009 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
|
+
require 'ftools'
|
|
19
|
+
require 'fileutils'
|
|
20
|
+
require 'tempfile'
|
|
21
|
+
|
|
22
|
+
class Chef
|
|
23
|
+
class Util
|
|
24
|
+
class FileEdit
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
attr_accessor :original_pathname, :contents, :file_edited
|
|
29
|
+
|
|
30
|
+
public
|
|
31
|
+
|
|
32
|
+
def initialize(filepath)
|
|
33
|
+
@original_pathname = filepath
|
|
34
|
+
@file_edited = false
|
|
35
|
+
|
|
36
|
+
raise ArgumentError, "File doesn't exist" unless File.exist? @original_pathname
|
|
37
|
+
raise ArgumentError, "File is blank" unless (@contents = File.new(@original_pathname).readlines).length > 0
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
#search the file line by line and match each line with the given regex
|
|
41
|
+
#if matched, replace the whole line with newline.
|
|
42
|
+
def search_file_replace_line(regex, newline)
|
|
43
|
+
search_match(regex, newline, 'r', 1)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#search the file line by line and match each line with the given regex
|
|
47
|
+
#if matched, replace the match (all occurances) with the replace parameter
|
|
48
|
+
def search_file_replace(regex, replace)
|
|
49
|
+
search_match(regex, replace, 'r', 2)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#search the file line by line and match each line with the given regex
|
|
53
|
+
#if matched, delete the line
|
|
54
|
+
def search_file_delete_line(regex)
|
|
55
|
+
search_match(regex, " ", 'd', 1)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
#search the file line by line and match each line with the given regex
|
|
59
|
+
#if matched, delete the match (all occurances) from the line
|
|
60
|
+
def search_file_delete(regex)
|
|
61
|
+
search_match(regex, " ", 'd', 2)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#search the file line by line and match each line with the given regex
|
|
65
|
+
#if matched, insert newline after each matching line
|
|
66
|
+
def insert_line_after_match(regex, newline)
|
|
67
|
+
search_match(regex, newline, 'i', 0)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#Make a copy of old_file and write new file out (only if file changed)
|
|
71
|
+
def write_file
|
|
72
|
+
|
|
73
|
+
# file_edited is false when there was no match in the whole file and thus no contents have changed.
|
|
74
|
+
if file_edited
|
|
75
|
+
backup_pathname = original_pathname + ".old"
|
|
76
|
+
File.copy(original_pathname, backup_pathname)
|
|
77
|
+
Tempfile.open("w") do |newfile|
|
|
78
|
+
contents.each do |line|
|
|
79
|
+
newfile.puts(line)
|
|
80
|
+
end
|
|
81
|
+
newfile.flush
|
|
82
|
+
FileUtils.mv(newfile.path, original_pathname)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
self.file_edited = false
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
#helper method to do the match, replace, delete, and insert operations
|
|
92
|
+
#command is the switch of delete, replace, and insert ('d', 'r', 'i')
|
|
93
|
+
#method is to control operation on whole line or only the match (1 for line, 2 for match)
|
|
94
|
+
def search_match(regex, replace, command, method)
|
|
95
|
+
|
|
96
|
+
#convert regex to a Regexp object (if not already is one) and store it in exp.
|
|
97
|
+
exp = Regexp.new(regex)
|
|
98
|
+
|
|
99
|
+
#loop through contents and do the appropriate operation depending on 'command' and 'method'
|
|
100
|
+
new_contents = []
|
|
101
|
+
|
|
102
|
+
contents.each do |line|
|
|
103
|
+
if line.match(exp)
|
|
104
|
+
self.file_edited = true
|
|
105
|
+
case
|
|
106
|
+
when command == 'r'
|
|
107
|
+
new_contents << ((method == 1) ? replace : line.gsub!(exp, replace))
|
|
108
|
+
when command == 'd'
|
|
109
|
+
if method == 2
|
|
110
|
+
new_contents << line.gsub!(exp, "")
|
|
111
|
+
end
|
|
112
|
+
when command == 'i'
|
|
113
|
+
new_contents << line
|
|
114
|
+
new_contents << replace
|
|
115
|
+
end
|
|
116
|
+
else
|
|
117
|
+
new_contents << line
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
self.contents = new_contents
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Nuo Yan (<nuo@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2009 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
|
+
require 'ftools'
|
|
19
|
+
require 'fileutils'
|
|
20
|
+
require 'tempfile'
|
|
21
|
+
|
|
22
|
+
class FileEdit
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
attr_accessor :original_pathname, :contents, :file_edited
|
|
27
|
+
|
|
28
|
+
public
|
|
29
|
+
|
|
30
|
+
def initialize(filepath)
|
|
31
|
+
@original_pathname = filepath
|
|
32
|
+
@file_edited = false
|
|
33
|
+
|
|
34
|
+
raise ArgumentError, "File doesn't exist" unless File.exist? @original_pathname
|
|
35
|
+
raise ArgumentError, "File is blank" unless (@contents = File.new(@original_pathname).readlines).length > 0
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#search the file line by line and match each line with the given regex
|
|
39
|
+
#if matched, replace the whole line with newline.
|
|
40
|
+
def search_file_replace_line(regex, newline)
|
|
41
|
+
search_match(regex, newline, 'r', 1)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#search the file line by line and match each line with the given regex
|
|
45
|
+
#if matched, replace the match (all occurances) with the replace parameter
|
|
46
|
+
def search_file_replace(regex, replace)
|
|
47
|
+
search_match(regex, replace, 'r', 2)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
#search the file line by line and match each line with the given regex
|
|
51
|
+
#if matched, delete the line
|
|
52
|
+
def search_file_delete_line(regex)
|
|
53
|
+
search_match(regex, " ", 'd', 1)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
#search the file line by line and match each line with the given regex
|
|
57
|
+
#if matched, delete the match (all occurances) from the line
|
|
58
|
+
def search_file_delete(regex)
|
|
59
|
+
search_match(regex, " ", 'd', 2)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#search the file line by line and match each line with the given regex
|
|
63
|
+
#if matched, insert newline after each matching line
|
|
64
|
+
def insert_line_after_match(regex, newline)
|
|
65
|
+
search_match(regex, newline, 'i', 0)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#Make a copy of old_file and write new file out (only if file changed)
|
|
69
|
+
def write_file
|
|
70
|
+
|
|
71
|
+
# file_edited is false when there was no match in the whole file and thus no contents have changed.
|
|
72
|
+
if file_edited
|
|
73
|
+
backup_pathname = original_pathname + ".old"
|
|
74
|
+
File.copy(original_pathname, backup_pathname)
|
|
75
|
+
Tempfile.open("w") do |newfile|
|
|
76
|
+
contents.each do |line|
|
|
77
|
+
newfile.puts(line)
|
|
78
|
+
end
|
|
79
|
+
newfile.flush
|
|
80
|
+
FileUtils.mv(newfile.path, original_pathname)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
self.file_edited = false
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
#helper method to do the match, replace, delete, and insert operations
|
|
90
|
+
#command is the switch of delete, replace, and insert ('d', 'r', 'i')
|
|
91
|
+
#method is to control operation on whole line or only the match (1 for line, 2 for match)
|
|
92
|
+
def search_match(regex, replace, command, method)
|
|
93
|
+
|
|
94
|
+
#convert regex to a Regexp object (if not already is one) and store it in exp.
|
|
95
|
+
exp = Regexp.new(regex)
|
|
96
|
+
|
|
97
|
+
#loop through contents and do the appropriate operation depending on 'command' and 'method'
|
|
98
|
+
new_contents = []
|
|
99
|
+
|
|
100
|
+
contents.each do |line|
|
|
101
|
+
if line.match(exp)
|
|
102
|
+
self.file_edited = true
|
|
103
|
+
case
|
|
104
|
+
when command == 'r'
|
|
105
|
+
new_contents << ((method == 1) ? replace : line.gsub!(exp, replace))
|
|
106
|
+
when command == 'd'
|
|
107
|
+
if method == 2
|
|
108
|
+
new_contents << line.gsub!(exp, "")
|
|
109
|
+
end
|
|
110
|
+
when command == 'i'
|
|
111
|
+
new_contents << line
|
|
112
|
+
new_contents << replace
|
|
113
|
+
end
|
|
114
|
+
else
|
|
115
|
+
new_contents << line
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
self.contents = new_contents
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
|
3
|
+
# Author:: Nuo Yan (<nuo@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
|
+
|
|
20
|
+
require 'chef/config'
|
|
21
|
+
require 'chef/mixin/params_validate'
|
|
22
|
+
require 'chef/couchdb'
|
|
23
|
+
require 'digest/sha1'
|
|
24
|
+
require 'rubygems'
|
|
25
|
+
require 'json'
|
|
26
|
+
|
|
27
|
+
class Chef
|
|
28
|
+
class WebUIUser
|
|
29
|
+
|
|
30
|
+
attr_accessor :name, :salt, :validated, :password, :couchdb_rev, :admin, :openid
|
|
31
|
+
|
|
32
|
+
include Chef::Mixin::ParamsValidate
|
|
33
|
+
|
|
34
|
+
DESIGN_DOCUMENT = {
|
|
35
|
+
"version" => 3,
|
|
36
|
+
"language" => "javascript",
|
|
37
|
+
"views" => {
|
|
38
|
+
"all" => {
|
|
39
|
+
"map" => <<-EOJS
|
|
40
|
+
function(doc) {
|
|
41
|
+
if (doc.chef_type == "webui_user") {
|
|
42
|
+
emit(doc.name, doc);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
EOJS
|
|
46
|
+
},
|
|
47
|
+
"all_id" => {
|
|
48
|
+
"map" => <<-EOJS
|
|
49
|
+
function(doc) {
|
|
50
|
+
if (doc.chef_type == "webui_user") {
|
|
51
|
+
emit(doc.name, doc.name);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
EOJS
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# Create a new Chef::WebUIUser object.
|
|
60
|
+
def initialize()
|
|
61
|
+
@name = nil
|
|
62
|
+
@salt = nil
|
|
63
|
+
@password = nil
|
|
64
|
+
@admin = false
|
|
65
|
+
@openid = nil
|
|
66
|
+
@couchdb_rev = nil
|
|
67
|
+
@couchdb = Chef::CouchDB.new
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def name=(n)
|
|
71
|
+
@name = n.gsub(/\./, '_')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Set the password for this object.
|
|
75
|
+
def set_password(password, confirm_password=password)
|
|
76
|
+
raise ArgumentError, "Passwords do not match" unless password == confirm_password
|
|
77
|
+
raise ArgumentError, "Password cannot be blank" if (password.nil? || password.length==0)
|
|
78
|
+
raise ArgumentError, "Password must be a minimum of 6 characters" if password.length < 6
|
|
79
|
+
@salt = generate_salt
|
|
80
|
+
@password = encrypt_password(@salt, password)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def set_openid(given_openid)
|
|
84
|
+
@openid = given_openid
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def verify_password(given_password)
|
|
88
|
+
encrypt_password(@salt, given_password) == @password ? true : false
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Serialize this object as a hash
|
|
92
|
+
def to_json(*a)
|
|
93
|
+
attributes = Hash.new
|
|
94
|
+
recipes = Array.new
|
|
95
|
+
result = {
|
|
96
|
+
'name' => @name,
|
|
97
|
+
'json_class' => self.class.name,
|
|
98
|
+
'salt' => @salt,
|
|
99
|
+
'password' => @password,
|
|
100
|
+
'openid' => @openid,
|
|
101
|
+
'admin' => @admin,
|
|
102
|
+
'chef_type' => 'webui_user',
|
|
103
|
+
}
|
|
104
|
+
result["_rev"] = @couchdb_rev if @couchdb_rev
|
|
105
|
+
result.to_json(*a)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Create a Chef::WebUIUser from JSON
|
|
109
|
+
def self.json_create(o)
|
|
110
|
+
me = new
|
|
111
|
+
me.name = o["name"]
|
|
112
|
+
me.salt = o["salt"]
|
|
113
|
+
me.password = o["password"]
|
|
114
|
+
me.openid = o["openid"]
|
|
115
|
+
me.admin = o["admin"]
|
|
116
|
+
me.couchdb_rev = o["_rev"] if o.has_key?("_rev")
|
|
117
|
+
me
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# List all the Chef::WebUIUser objects in the CouchDB. If inflate is set to true, you will get
|
|
121
|
+
# the full list of all registration objects. Otherwise, you'll just get the IDs
|
|
122
|
+
def self.cdb_list(inflate=false)
|
|
123
|
+
rs = Chef::CouchDB.new.list("users", inflate)
|
|
124
|
+
if inflate
|
|
125
|
+
rs["rows"].collect { |r| r["value"] }
|
|
126
|
+
else
|
|
127
|
+
rs["rows"].collect { |r| r["key"] }
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def self.list(inflate=false)
|
|
132
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
133
|
+
if inflate
|
|
134
|
+
response = Hash.new
|
|
135
|
+
Chef::Search::Query.new.search(:user) do |n|
|
|
136
|
+
response[n.name] = n unless n.nil?
|
|
137
|
+
end
|
|
138
|
+
response
|
|
139
|
+
else
|
|
140
|
+
r.get_rest("users")
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Load an WebUIUser by name from CouchDB
|
|
145
|
+
def self.cdb_load(name)
|
|
146
|
+
Chef::CouchDB.new.load("webui_user", name)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Load a User by name
|
|
150
|
+
def self.load(name)
|
|
151
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
152
|
+
r.get_rest("users/#{name}")
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
# Whether or not there is an WebUIUser with this key.
|
|
157
|
+
def self.has_key?(name)
|
|
158
|
+
Chef::CouchDB.new.has_key?("webui_user", name)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Remove this WebUIUser from the CouchDB
|
|
162
|
+
def cdb_destroy
|
|
163
|
+
@couchdb.delete("webui_user", @name, @couchdb_rev)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Remove this WebUIUser via the REST API
|
|
167
|
+
def destroy
|
|
168
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
169
|
+
r.delete_rest("users/#{@name}")
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Save this WebUIUser to the CouchDB
|
|
173
|
+
def cdb_save
|
|
174
|
+
results = @couchdb.store("webui_user", @name, self)
|
|
175
|
+
@couchdb_rev = results["rev"]
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Save this WebUIUser via the REST API
|
|
179
|
+
def save
|
|
180
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
181
|
+
begin
|
|
182
|
+
r.put_rest("users/#{@name}", self)
|
|
183
|
+
rescue Net::HTTPServerException => e
|
|
184
|
+
if e.response.code == "404"
|
|
185
|
+
r.post_rest("users", self)
|
|
186
|
+
else
|
|
187
|
+
raise e
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
self
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Create the WebUIUser via the REST API
|
|
194
|
+
def create
|
|
195
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
196
|
+
r.post_rest("users", self)
|
|
197
|
+
self
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Set up our CouchDB design document
|
|
201
|
+
def self.create_design_document
|
|
202
|
+
Chef::CouchDB.new.create_design_document("users", DESIGN_DOCUMENT)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
#return true if an admin user exists. this is pretty expensive (O(n)), should think of a better way (nuo)
|
|
206
|
+
def self.admin_exist
|
|
207
|
+
users = self.cdb_list
|
|
208
|
+
users.each do |u|
|
|
209
|
+
user = self.cdb_load(u)
|
|
210
|
+
if user.admin
|
|
211
|
+
return user.name
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
nil
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
protected
|
|
218
|
+
|
|
219
|
+
def generate_salt
|
|
220
|
+
salt = Time.now.to_s
|
|
221
|
+
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
|
222
|
+
1.upto(30) { |i| salt << chars[rand(chars.size-1)] }
|
|
223
|
+
salt
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def encrypt_password(salt, password)
|
|
227
|
+
Digest::SHA1.hexdigest("--#{salt}--#{password}--")
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
end
|
|
231
|
+
end
|