chef 0.10.0.beta.5 → 0.10.0.beta.6
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/lib/chef/application.rb +13 -1
- data/lib/chef/application/client.rb +4 -2
- data/lib/chef/application/knife.rb +26 -2
- data/lib/chef/application/solo.rb +4 -3
- data/lib/chef/client.rb +2 -1
- data/lib/chef/cookbook_version.rb +2 -1
- data/lib/chef/knife.rb +129 -37
- data/lib/chef/knife/cookbook_metadata.rb +8 -3
- data/lib/chef/knife/cookbook_site_install.rb +3 -127
- data/lib/chef/knife/cookbook_site_vendor.rb +46 -0
- data/lib/chef/knife/cookbook_test.rb +13 -2
- data/lib/chef/knife/core/cookbook_scm_repo.rb +149 -0
- data/lib/chef/knife/core/generic_presenter.rb +184 -0
- data/lib/chef/knife/core/node_editor.rb +127 -0
- data/lib/chef/knife/core/node_presenter.rb +103 -0
- data/lib/chef/knife/core/object_loader.rb +75 -0
- data/lib/chef/knife/{subcommand_loader.rb → core/subcommand_loader.rb} +1 -1
- data/lib/chef/knife/core/text_formatter.rb +100 -0
- data/lib/chef/knife/{ui.rb → core/ui.rb} +53 -73
- data/lib/chef/knife/data_bag_from_file.rb +8 -2
- data/lib/chef/knife/environment_from_file.rb +14 -3
- data/lib/chef/knife/node_edit.rb +14 -105
- data/lib/chef/knife/node_from_file.rb +6 -1
- data/lib/chef/knife/node_show.rb +6 -0
- data/lib/chef/knife/role_from_file.rb +6 -1
- data/lib/chef/knife/search.rb +34 -19
- data/lib/chef/knife/status.rb +15 -1
- data/lib/chef/mixin/recipe_definition_dsl_core.rb +1 -4
- data/lib/chef/mixin/shell_out.rb +1 -0
- data/lib/chef/node.rb +17 -5
- data/lib/chef/resource.rb +42 -19
- data/lib/chef/rest.rb +14 -6
- data/lib/chef/rest/auth_credentials.rb +1 -1
- data/lib/chef/rest/rest_request.rb +26 -1
- data/lib/chef/runner.rb +2 -9
- data/lib/chef/version.rb +1 -1
- metadata +11 -7
- data/lib/chef/knife/bootstrap/client-install.vbs +0 -80
- data/lib/chef/knife/bootstrap/windows-gems.erb +0 -34
- data/lib/chef/knife/windows_bootstrap.rb +0 -157
@@ -26,6 +26,7 @@ class Chef
|
|
26
26
|
deps do
|
27
27
|
require 'chef/data_bag'
|
28
28
|
require 'chef/data_bag_item'
|
29
|
+
require 'chef/knife/core/object_loader'
|
29
30
|
require 'chef/json_compat'
|
30
31
|
require 'chef/encrypted_data_bag_item'
|
31
32
|
end
|
@@ -58,12 +59,17 @@ class Chef
|
|
58
59
|
config[:secret] || config[:secret_file]
|
59
60
|
end
|
60
61
|
|
62
|
+
def loader
|
63
|
+
@loader ||= Knife::Core::ObjectLoader.new(DataBagItem, ui)
|
64
|
+
end
|
65
|
+
|
61
66
|
def run
|
62
67
|
if @name_args.size != 2
|
63
68
|
stdout.puts opt_parser
|
64
69
|
exit(1)
|
65
70
|
end
|
66
|
-
|
71
|
+
@data_bag, @item_path = @name_args[0], @name_args[1]
|
72
|
+
item = loader.load_from("data_bags", @data_bag, @item_path)
|
67
73
|
item = if use_encryption
|
68
74
|
secret = read_secret
|
69
75
|
Chef::EncryptedDataBagItem.encrypt_data_bag_item(item, secret)
|
@@ -74,7 +80,7 @@ class Chef
|
|
74
80
|
dbag.data_bag(@name_args[0])
|
75
81
|
dbag.raw_data = item
|
76
82
|
dbag.save
|
77
|
-
ui.info("Updated data_bag_item[#{
|
83
|
+
ui.info("Updated data_bag_item[#{dbag.data_bag}::#{dbag.id}]")
|
78
84
|
end
|
79
85
|
end
|
80
86
|
end
|
@@ -20,8 +20,18 @@ class Chef
|
|
20
20
|
class Knife
|
21
21
|
class EnvironmentFromFile < Knife
|
22
22
|
|
23
|
+
deps do
|
24
|
+
require 'chef/environment'
|
25
|
+
require 'chef/knife/core/object_loader'
|
26
|
+
end
|
27
|
+
|
23
28
|
banner "knife environment from file FILE (options)"
|
24
29
|
|
30
|
+
def loader
|
31
|
+
@loader ||= Knife::Core::ObjectLoader.new(Chef::Environment, ui)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
25
35
|
def run
|
26
36
|
if @name_args[0].nil?
|
27
37
|
show_usage
|
@@ -29,11 +39,12 @@ class Chef
|
|
29
39
|
exit 1
|
30
40
|
end
|
31
41
|
|
32
|
-
|
42
|
+
|
43
|
+
updated = loader.load_from("environments", @name_args[0])
|
33
44
|
updated.save
|
34
45
|
output(format_for_display(updated)) if config[:print_after]
|
35
|
-
ui.
|
46
|
+
ui.info("Updated Environment #{updated.name}")
|
36
47
|
end
|
37
48
|
end
|
38
49
|
end
|
39
|
-
end
|
50
|
+
end
|
data/lib/chef/knife/node_edit.rb
CHANGED
@@ -21,110 +21,14 @@ require 'chef/knife'
|
|
21
21
|
class Chef
|
22
22
|
class Knife
|
23
23
|
|
24
|
-
module NodeEditController
|
25
|
-
def edit_node
|
26
|
-
abort "You specified the --no-editor option, nothing to edit" if config[:no_editor]
|
27
|
-
assert_editor_set!
|
28
|
-
|
29
|
-
updated_node_data = edit_data(view)
|
30
|
-
apply_updates(updated_node_data)
|
31
|
-
@updated_node
|
32
|
-
end
|
33
|
-
|
34
|
-
def view
|
35
|
-
result = {}
|
36
|
-
result["name"] = node.name
|
37
|
-
result["chef_environment"] = node.chef_environment
|
38
|
-
result["normal"] = node.normal_attrs
|
39
|
-
result["run_list"] = node.run_list
|
40
|
-
|
41
|
-
if config[:all_attributes]
|
42
|
-
result["default"] = node.default_attrs
|
43
|
-
result["override"] = node.override_attrs
|
44
|
-
result["automatic"] = node.automatic_attrs
|
45
|
-
end
|
46
|
-
Chef::JSONCompat.to_json_pretty(result)
|
47
|
-
end
|
48
|
-
|
49
|
-
def edit_data(text)
|
50
|
-
edited_data = tempfile_for(text) {|filename| system("#{config[:editor]} #{filename}")}
|
51
|
-
Chef::JSONCompat.from_json(edited_data)
|
52
|
-
end
|
53
|
-
|
54
|
-
def apply_updates(updated_data)
|
55
|
-
# TODO: should warn/error/ask for confirmation when changing the
|
56
|
-
# name, since this results in a new node, not an edited node.
|
57
|
-
@updated_node = Node.new.tap do |n|
|
58
|
-
n.name( updated_data["name"] )
|
59
|
-
n.chef_environment( updated_data["chef_environment"] )
|
60
|
-
n.run_list( updated_data["run_list"])
|
61
|
-
n.normal_attrs = updated_data["normal"]
|
62
|
-
|
63
|
-
if config[:all_attributes]
|
64
|
-
n.default_attrs = updated_data["default"]
|
65
|
-
n.override_attrs = updated_data["override"]
|
66
|
-
n.automatic_attrs = updated_data["automatic"]
|
67
|
-
else
|
68
|
-
n.default_attrs = node.default_attrs
|
69
|
-
n.override_attrs = node.override_attrs
|
70
|
-
n.automatic_attrs = node.automatic_attrs
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def updated?
|
76
|
-
pristine_copy = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(node), :create_additions => false)
|
77
|
-
updated_copy = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@updated_node), :create_additions => false)
|
78
|
-
unless pristine_copy == updated_copy
|
79
|
-
updated_properties = %w{name normal chef_environment run_list default override automatic}.reject do |key|
|
80
|
-
pristine_copy[key] == updated_copy[key]
|
81
|
-
end
|
82
|
-
end
|
83
|
-
( pristine_copy != updated_copy ) && updated_properties
|
84
|
-
end
|
85
|
-
|
86
|
-
private
|
87
|
-
|
88
|
-
def abort(message)
|
89
|
-
STDERR.puts("ERROR: #{message}")
|
90
|
-
exit 1
|
91
|
-
end
|
92
|
-
|
93
|
-
def assert_editor_set!
|
94
|
-
unless config[:editor]
|
95
|
-
abort "You must set your EDITOR environment variable or configure your editor via knife.rb"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def tempfile_for(data)
|
100
|
-
# TODO: include useful info like the node name in the temp file
|
101
|
-
# name
|
102
|
-
basename = "knife-edit-" << rand(1_000_000_000_000_000).to_s.rjust(15, '0') << '.js'
|
103
|
-
filename = File.join(Dir.tmpdir, basename)
|
104
|
-
File.open(filename, "w+") do |f|
|
105
|
-
f.sync = true
|
106
|
-
f.puts data
|
107
|
-
end
|
108
|
-
|
109
|
-
yield filename
|
110
|
-
|
111
|
-
IO.read(filename)
|
112
|
-
ensure
|
113
|
-
File.unlink(filename)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
24
|
class NodeEdit < Knife
|
118
|
-
include NodeEditController
|
119
25
|
|
120
26
|
deps do
|
121
27
|
require 'chef/node'
|
122
28
|
require 'chef/json_compat'
|
29
|
+
require 'chef/knife/core/node_editor'
|
123
30
|
end
|
124
31
|
|
125
|
-
attr_reader :node_name
|
126
|
-
attr_reader :node
|
127
|
-
|
128
32
|
banner "knife node edit NODE (options)"
|
129
33
|
|
130
34
|
option :all_attributes,
|
@@ -134,17 +38,14 @@ class Chef
|
|
134
38
|
:description => "Display all attributes when editing"
|
135
39
|
|
136
40
|
def run
|
137
|
-
node_name = @name_args[0]
|
138
|
-
|
139
41
|
if node_name.nil?
|
140
42
|
show_usage
|
141
43
|
ui.fatal("You must specify a node name")
|
142
44
|
exit 1
|
143
45
|
end
|
144
46
|
|
145
|
-
|
146
|
-
|
147
|
-
if updated_values = updated?
|
47
|
+
updated_node = node_editor.edit_node
|
48
|
+
if updated_values = node_editor.updated?
|
148
49
|
ui.info "Saving updated #{updated_values.join(', ')} on node #{node.name}"
|
149
50
|
updated_node.save
|
150
51
|
else
|
@@ -152,10 +53,18 @@ class Chef
|
|
152
53
|
end
|
153
54
|
end
|
154
55
|
|
155
|
-
def
|
156
|
-
@
|
157
|
-
|
56
|
+
def node_name
|
57
|
+
@node_name ||= @name_args[0]
|
58
|
+
end
|
59
|
+
|
60
|
+
def node_editor
|
61
|
+
@node_editor ||= Knife::NodeEditor.new(node, ui, config)
|
62
|
+
end
|
63
|
+
|
64
|
+
def node
|
65
|
+
@node ||= Chef::Node.load(node_name)
|
158
66
|
end
|
67
|
+
|
159
68
|
end
|
160
69
|
end
|
161
70
|
end
|
@@ -25,12 +25,17 @@ class Chef
|
|
25
25
|
deps do
|
26
26
|
require 'chef/node'
|
27
27
|
require 'chef/json_compat'
|
28
|
+
require 'chef/knife/core/object_loader'
|
28
29
|
end
|
29
30
|
|
30
31
|
banner "knife node from file FILE (options)"
|
31
32
|
|
33
|
+
def loader
|
34
|
+
@loader ||= Knife::Core::ObjectLoader.new(Chef::Node, ui)
|
35
|
+
end
|
36
|
+
|
32
37
|
def run
|
33
|
-
updated =
|
38
|
+
updated = loader.load_from('nodes', @name_args[0])
|
34
39
|
|
35
40
|
updated.save
|
36
41
|
|
data/lib/chef/knife/node_show.rb
CHANGED
@@ -17,11 +17,14 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'chef/knife'
|
20
|
+
require 'chef/knife/core/node_presenter'
|
20
21
|
|
21
22
|
class Chef
|
22
23
|
class Knife
|
23
24
|
class NodeShow < Knife
|
24
25
|
|
26
|
+
include Knife::Core::NodeFormattingOptions
|
27
|
+
|
25
28
|
deps do
|
26
29
|
require 'chef/node'
|
27
30
|
require 'chef/json_compat'
|
@@ -29,9 +32,11 @@ class Chef
|
|
29
32
|
|
30
33
|
banner "knife node show NODE (options)"
|
31
34
|
|
35
|
+
attrs_to_show = []
|
32
36
|
option :attribute,
|
33
37
|
:short => "-a [ATTR]",
|
34
38
|
:long => "--attribute [ATTR]",
|
39
|
+
:proc => lambda {|val| attrs_to_show << val},
|
35
40
|
:description => "Show only one attribute"
|
36
41
|
|
37
42
|
option :run_list,
|
@@ -45,6 +50,7 @@ class Chef
|
|
45
50
|
:description => "Show only the Chef environment"
|
46
51
|
|
47
52
|
def run
|
53
|
+
ui.use_presenter Knife::Core::NodePresenter
|
48
54
|
@node_name = @name_args[0]
|
49
55
|
|
50
56
|
if @node_name.nil?
|
@@ -24,13 +24,18 @@ class Chef
|
|
24
24
|
|
25
25
|
deps do
|
26
26
|
require 'chef/role'
|
27
|
+
require 'chef/knife/core/object_loader'
|
27
28
|
require 'chef/json_compat'
|
28
29
|
end
|
29
30
|
|
30
31
|
banner "knife role from file FILE (options)"
|
31
32
|
|
33
|
+
def loader
|
34
|
+
@loader ||= Knife::Core::ObjectLoader.new(Chef::Role, ui)
|
35
|
+
end
|
36
|
+
|
32
37
|
def run
|
33
|
-
updated =
|
38
|
+
updated = loader.load_from("roles", @name_args[0])
|
34
39
|
|
35
40
|
updated.save
|
36
41
|
|
data/lib/chef/knife/search.rb
CHANGED
@@ -24,8 +24,11 @@ class Chef
|
|
24
24
|
|
25
25
|
deps do
|
26
26
|
require 'chef/search/query'
|
27
|
+
require 'chef/knife/core/node_presenter'
|
27
28
|
end
|
28
29
|
|
30
|
+
include Knife::Core::NodeFormattingOptions
|
31
|
+
|
29
32
|
banner "knife search INDEX QUERY (options)"
|
30
33
|
|
31
34
|
option :sort,
|
@@ -70,48 +73,60 @@ class Chef
|
|
70
73
|
|
71
74
|
def run
|
72
75
|
if config[:query] && @name_args[1]
|
73
|
-
|
74
|
-
|
76
|
+
ui.error "please specify query as an argument or an option via -q, not both"
|
77
|
+
ui.msg opt_parser
|
75
78
|
exit 1
|
76
79
|
end
|
77
80
|
raw_query = config[:query] || @name_args[1]
|
78
81
|
if !raw_query || raw_query.empty?
|
79
|
-
|
80
|
-
|
82
|
+
ui.error "no query specified"
|
83
|
+
ui.msg opt_parser
|
84
|
+
exit 1
|
85
|
+
end
|
86
|
+
|
87
|
+
if name_args[0].nil?
|
88
|
+
ui.error "you must specify an item type to search for"
|
81
89
|
exit 1
|
82
90
|
end
|
83
91
|
|
92
|
+
if name_args[0] == 'node'
|
93
|
+
ui.use_presenter Knife::Core::NodePresenter
|
94
|
+
end
|
95
|
+
|
96
|
+
|
84
97
|
q = Chef::Search::Query.new
|
85
|
-
display = { :total => 0, :start => config[:start] ? config[:start] : 0, :rows => [ ] }
|
86
98
|
query = URI.escape(raw_query,
|
87
99
|
Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
88
|
-
|
89
|
-
|
100
|
+
|
101
|
+
result_items = []
|
102
|
+
result_count = 0
|
103
|
+
|
104
|
+
rows = config[:rows]
|
105
|
+
start = config[:start]
|
90
106
|
begin
|
91
107
|
q.search(@name_args[0], query, config[:sort], start, rows) do |item|
|
92
108
|
formatted_item = format_for_display(item)
|
93
109
|
if formatted_item.respond_to?(:has_key?) && !formatted_item.has_key?('id')
|
94
110
|
formatted_item['id'] = item.has_key?('id') ? item['id'] : item.name
|
95
111
|
end
|
96
|
-
|
97
|
-
|
112
|
+
result_items << formatted_item
|
113
|
+
result_count += 1
|
98
114
|
end
|
99
115
|
rescue Net::HTTPServerException => e
|
100
116
|
msg = Chef::JSONCompat.from_json(e.response.body)["error"].first
|
101
|
-
ui.
|
117
|
+
ui.error("knife search failed: #{msg}")
|
102
118
|
exit 1
|
103
119
|
end
|
104
120
|
|
105
|
-
if
|
106
|
-
|
107
|
-
display[:rows].each do |row|
|
108
|
-
puts row[config[:attribute]] if row.has_key?(config[:attribute]) && !row[config[:attribute]].nil?
|
109
|
-
end
|
110
|
-
else
|
111
|
-
puts display[:rows].join("\n")
|
112
|
-
end
|
121
|
+
if ui.interchange?
|
122
|
+
output({:results => result_count, :rows => result_items})
|
113
123
|
else
|
114
|
-
|
124
|
+
ui.msg "#{result_count} items found"
|
125
|
+
ui.msg("\n")
|
126
|
+
result_items.each do |item|
|
127
|
+
output(item)
|
128
|
+
ui.msg("\n")
|
129
|
+
end
|
115
130
|
end
|
116
131
|
end
|
117
132
|
end
|
data/lib/chef/knife/status.rb
CHANGED
@@ -68,7 +68,21 @@ class Chef
|
|
68
68
|
text = minutes_text
|
69
69
|
end
|
70
70
|
|
71
|
-
|
71
|
+
line_parts = Array.new
|
72
|
+
line_parts << "<%= color('#{text}', #{color}) %> ago" << node.name
|
73
|
+
line_parts << fqdn if fqdn
|
74
|
+
line_parts << ipaddress if ipaddress
|
75
|
+
line_parts << run_list if run_list
|
76
|
+
|
77
|
+
if node['platform']
|
78
|
+
platform = node['platform']
|
79
|
+
if node['platform_version']
|
80
|
+
platform << " #{node['platform_version']}"
|
81
|
+
end
|
82
|
+
line_parts << platform
|
83
|
+
end
|
84
|
+
|
85
|
+
highline.say(line_parts.join(', ') + '.')
|
72
86
|
end
|
73
87
|
|
74
88
|
end
|
@@ -61,10 +61,7 @@ class Chef
|
|
61
61
|
resource = Chef::Resource.const_get(rname).new(*args)
|
62
62
|
resource.load_prior_resource
|
63
63
|
resource.cookbook_name = cookbook_name
|
64
|
-
|
65
|
-
# anything? it's not even possible that this ivar is set on
|
66
|
-
# Chef::Provider.
|
67
|
-
# resource.recipe_name = @recipe_name
|
64
|
+
resource.recipe_name = @recipe_name
|
68
65
|
resource.params = @params
|
69
66
|
resource.source_line = caller[0]
|
70
67
|
# Determine whether this resource is being created in the context of an enclosing Provider
|
data/lib/chef/mixin/shell_out.rb
CHANGED
data/lib/chef/node.rb
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
# limitations under the License.
|
20
20
|
#
|
21
21
|
|
22
|
+
require 'forwardable'
|
22
23
|
require 'chef/config'
|
23
24
|
require 'chef/cookbook/cookbook_collection'
|
24
25
|
require 'chef/nil_argument'
|
@@ -39,6 +40,10 @@ require 'chef/json_compat'
|
|
39
40
|
class Chef
|
40
41
|
class Node
|
41
42
|
|
43
|
+
extend Forwardable
|
44
|
+
|
45
|
+
def_delegators :construct_attributes, :keys, :each_key, :each_value, :key?, :has_key?
|
46
|
+
|
42
47
|
attr_accessor :recipe_list, :couchdb, :couchdb_rev, :run_state, :run_list
|
43
48
|
attr_accessor :override_attrs, :default_attrs, :normal_attrs, :automatic_attrs
|
44
49
|
attr_reader :couchdb_id
|
@@ -363,11 +368,6 @@ class Chef
|
|
363
368
|
args.length > 0 ? @run_list.reset!(args) : @run_list
|
364
369
|
end
|
365
370
|
|
366
|
-
def recipes(*args)
|
367
|
-
Chef::Log.warn "Chef::Node#recipes method is deprecated. Please use Chef::Node#run_list"
|
368
|
-
run_list(*args)
|
369
|
-
end
|
370
|
-
|
371
371
|
# Returns true if this Node expects a given role, false if not.
|
372
372
|
def run_list?(item)
|
373
373
|
run_list.detect { |r| r == item } ? true : false
|
@@ -468,6 +468,18 @@ class Chef
|
|
468
468
|
index_hash
|
469
469
|
end
|
470
470
|
|
471
|
+
def display_hash
|
472
|
+
display = {}
|
473
|
+
display["name"] = name
|
474
|
+
display["chef_environment"] = chef_environment
|
475
|
+
display["automatic"] = automatic_attrs
|
476
|
+
display["normal"] = normal_attrs
|
477
|
+
display["default"] = default_attrs
|
478
|
+
display["override"] = override_attrs
|
479
|
+
display["run_list"] = run_list.run_list
|
480
|
+
display
|
481
|
+
end
|
482
|
+
|
471
483
|
# Serialize this object as a hash
|
472
484
|
def to_json(*a)
|
473
485
|
result = {
|