cheffish 1.6.0 → 2.0.0
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.
- checksums.yaml +4 -4
- data/cheffish.gemspec +1 -0
- data/lib/chef/resource/chef_acl.rb +440 -20
- data/lib/chef/resource/chef_client.rb +50 -25
- data/lib/chef/resource/chef_container.rb +44 -11
- data/lib/chef/resource/chef_data_bag.rb +43 -10
- data/lib/chef/resource/chef_data_bag_item.rb +292 -82
- data/lib/chef/resource/chef_environment.rb +79 -27
- data/lib/chef/resource/chef_group.rb +77 -40
- data/lib/chef/resource/chef_mirror.rb +170 -21
- data/lib/chef/resource/chef_node.rb +77 -11
- data/lib/chef/resource/chef_organization.rb +153 -43
- data/lib/chef/resource/chef_resolved_cookbooks.rb +40 -9
- data/lib/chef/resource/chef_role.rb +81 -29
- data/lib/chef/resource/chef_user.rb +64 -33
- data/lib/chef/resource/private_key.rb +230 -17
- data/lib/chef/resource/public_key.rb +88 -9
- data/lib/cheffish/array_property.rb +29 -0
- data/lib/cheffish/base_resource.rb +254 -0
- data/lib/cheffish/chef_actor_base.rb +135 -0
- data/lib/cheffish/node_properties.rb +107 -0
- data/lib/cheffish/recipe_dsl.rb +0 -14
- data/lib/cheffish/version.rb +1 -1
- data/lib/cheffish.rb +4 -108
- data/spec/integration/chef_acl_spec.rb +0 -2
- data/spec/integration/chef_client_spec.rb +0 -1
- data/spec/integration/chef_container_spec.rb +0 -2
- data/spec/integration/chef_group_spec.rb +0 -2
- data/spec/integration/chef_mirror_spec.rb +0 -2
- data/spec/integration/chef_node_spec.rb +0 -2
- data/spec/integration/chef_organization_spec.rb +1 -3
- data/spec/integration/chef_role_spec.rb +0 -2
- data/spec/integration/chef_user_spec.rb +0 -2
- data/spec/integration/private_key_spec.rb +0 -4
- data/spec/integration/recipe_dsl_spec.rb +0 -2
- data/spec/support/spec_support.rb +0 -1
- data/spec/unit/get_private_key_spec.rb +13 -0
- metadata +22 -20
- data/lib/chef/provider/chef_acl.rb +0 -446
- data/lib/chef/provider/chef_client.rb +0 -53
- data/lib/chef/provider/chef_container.rb +0 -55
- data/lib/chef/provider/chef_data_bag.rb +0 -55
- data/lib/chef/provider/chef_data_bag_item.rb +0 -278
- data/lib/chef/provider/chef_environment.rb +0 -83
- data/lib/chef/provider/chef_group.rb +0 -83
- data/lib/chef/provider/chef_mirror.rb +0 -169
- data/lib/chef/provider/chef_node.rb +0 -87
- data/lib/chef/provider/chef_organization.rb +0 -155
- data/lib/chef/provider/chef_resolved_cookbooks.rb +0 -46
- data/lib/chef/provider/chef_role.rb +0 -84
- data/lib/chef/provider/chef_user.rb +0 -59
- data/lib/chef/provider/private_key.rb +0 -225
- data/lib/chef/provider/public_key.rb +0 -88
- data/lib/cheffish/actor_provider_base.rb +0 -131
- data/lib/cheffish/chef_provider_base.rb +0 -246
@@ -1,155 +0,0 @@
|
|
1
|
-
require 'cheffish/chef_provider_base'
|
2
|
-
require 'chef/resource/chef_organization'
|
3
|
-
require 'chef/chef_fs/data_handler/data_handler_base'
|
4
|
-
|
5
|
-
class Chef
|
6
|
-
class Provider
|
7
|
-
class ChefOrganization < Cheffish::ChefProviderBase
|
8
|
-
provides :chef_organization
|
9
|
-
|
10
|
-
def whyrun_supported?
|
11
|
-
true
|
12
|
-
end
|
13
|
-
|
14
|
-
action :create do
|
15
|
-
differences = json_differences(current_json, new_json)
|
16
|
-
|
17
|
-
if current_resource_exists?
|
18
|
-
if differences.size > 0
|
19
|
-
description = [ "update organization #{new_resource.name} at #{rest.url}" ] + differences
|
20
|
-
converge_by description do
|
21
|
-
rest.put("#{rest.root_url}/organizations/#{new_resource.name}", normalize_for_put(new_json))
|
22
|
-
end
|
23
|
-
end
|
24
|
-
else
|
25
|
-
description = [ "create organization #{new_resource.name} at #{rest.url}" ] + differences
|
26
|
-
converge_by description do
|
27
|
-
rest.post("#{rest.root_url}/organizations", normalize_for_post(new_json))
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# Revoke invites and memberships when asked
|
32
|
-
invites_to_remove.each do |user|
|
33
|
-
if outstanding_invites.has_key?(user)
|
34
|
-
converge_by "revoke #{user}'s invitation to organization #{new_resource.name}" do
|
35
|
-
rest.delete("#{rest.root_url}/organizations/#{new_resource.name}/association_requests/#{outstanding_invites[user]}")
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
members_to_remove.each do |user|
|
40
|
-
if existing_members.include?(user)
|
41
|
-
converge_by "remove #{user} from organization #{new_resource.name}" do
|
42
|
-
rest.delete("#{rest.root_url}/organizations/#{new_resource.name}/users/#{user}")
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Invite and add members when asked
|
48
|
-
new_resource.invites.each do |user|
|
49
|
-
if !existing_members.include?(user) && !outstanding_invites.has_key?(user)
|
50
|
-
converge_by "invite #{user} to organization #{new_resource.name}" do
|
51
|
-
rest.post("#{rest.root_url}/organizations/#{new_resource.name}/association_requests", { 'user' => user })
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
new_resource.members.each do |user|
|
56
|
-
if !existing_members.include?(user)
|
57
|
-
converge_by "Add #{user} to organization #{new_resource.name}" do
|
58
|
-
rest.post("#{rest.root_url}/organizations/#{new_resource.name}/users/", { 'username' => user })
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def existing_members
|
65
|
-
@existing_members ||= rest.get("#{rest.root_url}/organizations/#{new_resource.name}/users").map { |u| u['user']['username'] }
|
66
|
-
end
|
67
|
-
|
68
|
-
def outstanding_invites
|
69
|
-
@outstanding_invites ||= begin
|
70
|
-
invites = {}
|
71
|
-
rest.get("#{rest.root_url}/organizations/#{new_resource.name}/association_requests").each do |r|
|
72
|
-
invites[r['username']] = r['id']
|
73
|
-
end
|
74
|
-
invites
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def invites_to_remove
|
79
|
-
if new_resource.complete
|
80
|
-
if new_resource.invites_specified? || new_resource.members_specified?
|
81
|
-
outstanding_invites.keys - (new_resource.invites | new_resource.members)
|
82
|
-
else
|
83
|
-
[]
|
84
|
-
end
|
85
|
-
else
|
86
|
-
new_resource.remove_members
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def members_to_remove
|
91
|
-
if new_resource.complete
|
92
|
-
if new_resource.members_specified?
|
93
|
-
existing_members - (new_resource.invites | new_resource.members)
|
94
|
-
else
|
95
|
-
[]
|
96
|
-
end
|
97
|
-
else
|
98
|
-
new_resource.remove_members
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
action :delete do
|
103
|
-
if current_resource_exists?
|
104
|
-
converge_by "delete organization #{new_resource.name} at #{rest.url}" do
|
105
|
-
rest.delete("#{rest.root_url}/organizations/#{new_resource.name}")
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def load_current_resource
|
111
|
-
begin
|
112
|
-
@current_resource = json_to_resource(rest.get("#{rest.root_url}/organizations/#{new_resource.name}"))
|
113
|
-
rescue Net::HTTPServerException => e
|
114
|
-
if e.response.code == "404"
|
115
|
-
@current_resource = not_found_resource
|
116
|
-
else
|
117
|
-
raise
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
#
|
123
|
-
# Helpers
|
124
|
-
#
|
125
|
-
|
126
|
-
def resource_class
|
127
|
-
Chef::Resource::ChefOrganization
|
128
|
-
end
|
129
|
-
|
130
|
-
def data_handler
|
131
|
-
OrganizationDataHandler.new
|
132
|
-
end
|
133
|
-
|
134
|
-
def keys
|
135
|
-
{
|
136
|
-
'name' => :name,
|
137
|
-
'full_name' => :full_name
|
138
|
-
}
|
139
|
-
end
|
140
|
-
|
141
|
-
class OrganizationDataHandler < Chef::ChefFS::DataHandler::DataHandlerBase
|
142
|
-
def normalize(organization, entry)
|
143
|
-
# Normalize the order of the keys for easier reading
|
144
|
-
normalize_hash(organization, {
|
145
|
-
'name' => remove_dot_json(entry.name),
|
146
|
-
'full_name' => remove_dot_json(entry.name),
|
147
|
-
'org_type' => 'Business',
|
148
|
-
'clientname' => "#{remove_dot_json(entry.name)}-validator",
|
149
|
-
'billing_plan' => 'platform-free'
|
150
|
-
})
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'chef/provider/lwrp_base'
|
2
|
-
require 'chef_zero'
|
3
|
-
|
4
|
-
class Chef
|
5
|
-
class Provider
|
6
|
-
class ChefResolvedCookbooks < Chef::Provider::LWRPBase
|
7
|
-
provides :chef_resolved_cookbooks
|
8
|
-
|
9
|
-
action :resolve do
|
10
|
-
new_resource.cookbooks_from.each do |path|
|
11
|
-
::Dir.entries(path).each do |name|
|
12
|
-
if ::File.directory?(::File.join(path, name)) && name != '.' && name != '..'
|
13
|
-
new_resource.berksfile.cookbook name, :path => ::File.join(path, name)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
new_resource.berksfile.install
|
19
|
-
|
20
|
-
# Ridley really really wants a key :/
|
21
|
-
if new_resource.chef_server[:options][:signing_key_filename]
|
22
|
-
new_resource.berksfile.upload(
|
23
|
-
:server_url => new_resource.chef_server[:chef_server_url],
|
24
|
-
:client_name => new_resource.chef_server[:options][:client_name],
|
25
|
-
:client_key => new_resource.chef_server[:options][:signing_key_filename])
|
26
|
-
else
|
27
|
-
file = Tempfile.new('privatekey')
|
28
|
-
begin
|
29
|
-
file.write(ChefZero::PRIVATE_KEY)
|
30
|
-
file.close
|
31
|
-
|
32
|
-
new_resource.berksfile.upload(
|
33
|
-
:server_url => new_resource.chef_server[:chef_server_url],
|
34
|
-
:client_name => new_resource.chef_server[:options][:client_name] || 'me',
|
35
|
-
:client_key => file.path)
|
36
|
-
|
37
|
-
ensure
|
38
|
-
file.close
|
39
|
-
file.unlink
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'cheffish/chef_provider_base'
|
2
|
-
require 'chef/resource/chef_role'
|
3
|
-
require 'chef/chef_fs/data_handler/role_data_handler'
|
4
|
-
|
5
|
-
class Chef
|
6
|
-
class Provider
|
7
|
-
class ChefRole < Cheffish::ChefProviderBase
|
8
|
-
provides :chef_role
|
9
|
-
|
10
|
-
def whyrun_supported?
|
11
|
-
true
|
12
|
-
end
|
13
|
-
|
14
|
-
action :create do
|
15
|
-
differences = json_differences(current_json, new_json)
|
16
|
-
|
17
|
-
if current_resource_exists?
|
18
|
-
if differences.size > 0
|
19
|
-
description = [ "update role #{new_resource.name} at #{rest.url}" ] + differences
|
20
|
-
converge_by description do
|
21
|
-
rest.put("roles/#{new_resource.name}", normalize_for_put(new_json))
|
22
|
-
end
|
23
|
-
end
|
24
|
-
else
|
25
|
-
description = [ "create role #{new_resource.name} at #{rest.url}" ] + differences
|
26
|
-
converge_by description do
|
27
|
-
rest.post("roles", normalize_for_post(new_json))
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
action :delete do
|
33
|
-
if current_resource_exists?
|
34
|
-
converge_by "delete role #{new_resource.name} at #{rest.url}" do
|
35
|
-
rest.delete("roles/#{new_resource.name}")
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def load_current_resource
|
41
|
-
begin
|
42
|
-
@current_resource = json_to_resource(rest.get("roles/#{new_resource.name}"))
|
43
|
-
rescue Net::HTTPServerException => e
|
44
|
-
if e.response.code == "404"
|
45
|
-
@current_resource = not_found_resource
|
46
|
-
else
|
47
|
-
raise
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def augment_new_json(json)
|
53
|
-
# Apply modifiers
|
54
|
-
json['run_list'] = apply_run_list_modifiers(new_resource.run_list_modifiers, new_resource.run_list_removers, json['run_list'])
|
55
|
-
json['default_attributes'] = apply_modifiers(new_resource.default_attribute_modifiers, json['default_attributes'])
|
56
|
-
json['override_attributes'] = apply_modifiers(new_resource.override_attribute_modifiers, json['override_attributes'])
|
57
|
-
json
|
58
|
-
end
|
59
|
-
|
60
|
-
#
|
61
|
-
# Helpers
|
62
|
-
#
|
63
|
-
|
64
|
-
def resource_class
|
65
|
-
Chef::Resource::ChefRole
|
66
|
-
end
|
67
|
-
|
68
|
-
def data_handler
|
69
|
-
Chef::ChefFS::DataHandler::RoleDataHandler.new
|
70
|
-
end
|
71
|
-
|
72
|
-
def keys
|
73
|
-
{
|
74
|
-
'name' => :name,
|
75
|
-
'description' => :description,
|
76
|
-
'run_list' => :run_list,
|
77
|
-
'env_run_lists' => :env_run_lists,
|
78
|
-
'default_attributes' => :default_attributes,
|
79
|
-
'override_attributes' => :override_attributes
|
80
|
-
}
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
require 'cheffish/actor_provider_base'
|
2
|
-
require 'chef/resource/chef_user'
|
3
|
-
require 'chef/chef_fs/data_handler/user_data_handler'
|
4
|
-
|
5
|
-
class Chef
|
6
|
-
class Provider
|
7
|
-
class ChefUser < Cheffish::ActorProviderBase
|
8
|
-
provides :chef_user
|
9
|
-
|
10
|
-
def whyrun_supported?
|
11
|
-
true
|
12
|
-
end
|
13
|
-
|
14
|
-
action :create do
|
15
|
-
create_actor
|
16
|
-
end
|
17
|
-
|
18
|
-
action :delete do
|
19
|
-
delete_actor
|
20
|
-
end
|
21
|
-
|
22
|
-
#
|
23
|
-
# Helpers
|
24
|
-
#
|
25
|
-
# Gives us new_json, current_json, not_found_json, etc.
|
26
|
-
|
27
|
-
def actor_type
|
28
|
-
'user'
|
29
|
-
end
|
30
|
-
|
31
|
-
def actor_path
|
32
|
-
"#{rest.root_url}/users"
|
33
|
-
end
|
34
|
-
|
35
|
-
def resource_class
|
36
|
-
Chef::Resource::ChefUser
|
37
|
-
end
|
38
|
-
|
39
|
-
def data_handler
|
40
|
-
Chef::ChefFS::DataHandler::UserDataHandler.new
|
41
|
-
end
|
42
|
-
|
43
|
-
def keys
|
44
|
-
{
|
45
|
-
'name' => :name,
|
46
|
-
'username' => :name,
|
47
|
-
'display_name' => :display_name,
|
48
|
-
'admin' => :admin,
|
49
|
-
'email' => :email,
|
50
|
-
'password' => :password,
|
51
|
-
'external_authentication_uid' => :external_authentication_uid,
|
52
|
-
'recovery_authentication_enabled' => :recovery_authentication_enabled,
|
53
|
-
'public_key' => :source_key
|
54
|
-
}
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,225 +0,0 @@
|
|
1
|
-
require 'chef/provider/lwrp_base'
|
2
|
-
require 'openssl'
|
3
|
-
require 'cheffish/key_formatter'
|
4
|
-
|
5
|
-
class Chef
|
6
|
-
class Provider
|
7
|
-
class PrivateKey < Chef::Provider::LWRPBase
|
8
|
-
provides :private_key
|
9
|
-
|
10
|
-
action :create do
|
11
|
-
create_key(false, :create)
|
12
|
-
end
|
13
|
-
|
14
|
-
action :regenerate do
|
15
|
-
create_key(true, :regenerate)
|
16
|
-
end
|
17
|
-
|
18
|
-
action :delete do
|
19
|
-
if current_resource.path
|
20
|
-
converge_by "delete private key #{new_path}" do
|
21
|
-
::File.unlink(new_path)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
use_inline_resources
|
27
|
-
|
28
|
-
def whyrun_supported?
|
29
|
-
true
|
30
|
-
end
|
31
|
-
|
32
|
-
def create_key(regenerate, action)
|
33
|
-
if @should_create_directory
|
34
|
-
Cheffish.inline_resource(self, action) do
|
35
|
-
directory run_context.config[:private_key_write_path]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
final_private_key = nil
|
40
|
-
if new_source_key
|
41
|
-
#
|
42
|
-
# Create private key from source
|
43
|
-
#
|
44
|
-
desired_output = encode_private_key(new_source_key)
|
45
|
-
if current_resource.path == :none || desired_output != IO.read(new_path)
|
46
|
-
converge_by "reformat key at #{new_resource.source_key_path} to #{new_resource.format} private key #{new_path} (#{new_resource.pass_phrase ? ", #{new_resource.cipher} password" : ""})" do
|
47
|
-
IO.write(new_path, desired_output)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
final_private_key = new_source_key
|
52
|
-
|
53
|
-
else
|
54
|
-
#
|
55
|
-
# Generate a new key
|
56
|
-
#
|
57
|
-
if current_resource.action == [ :delete ] || regenerate ||
|
58
|
-
(new_resource.regenerate_if_different &&
|
59
|
-
(!current_private_key ||
|
60
|
-
current_resource.size != new_resource.size ||
|
61
|
-
current_resource.type != new_resource.type))
|
62
|
-
|
63
|
-
case new_resource.type
|
64
|
-
when :rsa
|
65
|
-
if new_resource.exponent
|
66
|
-
final_private_key = OpenSSL::PKey::RSA.generate(new_resource.size, new_resource.exponent)
|
67
|
-
else
|
68
|
-
final_private_key = OpenSSL::PKey::RSA.generate(new_resource.size)
|
69
|
-
end
|
70
|
-
when :dsa
|
71
|
-
final_private_key = OpenSSL::PKey::DSA.generate(new_resource.size)
|
72
|
-
end
|
73
|
-
|
74
|
-
generated_key = true
|
75
|
-
elsif !current_private_key
|
76
|
-
raise "Could not read private key from #{current_resource.path}: missing pass phrase?"
|
77
|
-
else
|
78
|
-
final_private_key = current_private_key
|
79
|
-
generated_key = false
|
80
|
-
end
|
81
|
-
|
82
|
-
if generated_key
|
83
|
-
generated_description = " (#{new_resource.size} bits#{new_resource.pass_phrase ? ", #{new_resource.cipher} password" : ""})"
|
84
|
-
|
85
|
-
if new_path != :none
|
86
|
-
action = current_resource.path == :none ? 'create' : 'overwrite'
|
87
|
-
converge_by "#{action} #{new_resource.type} private key #{new_path}#{generated_description}" do
|
88
|
-
write_private_key(final_private_key)
|
89
|
-
end
|
90
|
-
else
|
91
|
-
converge_by "generate private key#{generated_description}" do
|
92
|
-
end
|
93
|
-
end
|
94
|
-
else
|
95
|
-
# Warn if existing key has different characteristics than expected
|
96
|
-
if current_resource.size != new_resource.size
|
97
|
-
Chef::Log.warn("Mismatched key size! #{current_resource.path} is #{current_resource.size} bytes, desired is #{new_resource.size} bytes. Use action :regenerate to force key regeneration.")
|
98
|
-
elsif current_resource.type != new_resource.type
|
99
|
-
Chef::Log.warn("Mismatched key type! #{current_resource.path} is #{current_resource.type}, desired is #{new_resource.type} bytes. Use action :regenerate to force key regeneration.")
|
100
|
-
end
|
101
|
-
|
102
|
-
if current_resource.format != new_resource.format
|
103
|
-
converge_by "change format of #{new_resource.type} private key #{new_path} from #{current_resource.format} to #{new_resource.format}" do
|
104
|
-
write_private_key(current_private_key)
|
105
|
-
end
|
106
|
-
elsif (@current_file_mode & 0077) != 0
|
107
|
-
new_mode = @current_file_mode & 07700
|
108
|
-
converge_by "change mode of private key #{new_path} to #{new_mode.to_s(8)}" do
|
109
|
-
::File.chmod(new_mode, new_path)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
if new_resource.public_key_path
|
116
|
-
public_key_path = new_resource.public_key_path
|
117
|
-
public_key_format = new_resource.public_key_format
|
118
|
-
Cheffish.inline_resource(self, action) do
|
119
|
-
public_key public_key_path do
|
120
|
-
source_key final_private_key
|
121
|
-
format public_key_format
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
if new_resource.after
|
127
|
-
new_resource.after.call(new_resource, final_private_key)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def encode_private_key(key)
|
132
|
-
key_format = {}
|
133
|
-
key_format[:format] = new_resource.format if new_resource.format
|
134
|
-
key_format[:pass_phrase] = new_resource.pass_phrase if new_resource.pass_phrase
|
135
|
-
key_format[:cipher] = new_resource.cipher if new_resource.cipher
|
136
|
-
Cheffish::KeyFormatter.encode(key, key_format)
|
137
|
-
end
|
138
|
-
|
139
|
-
def write_private_key(key)
|
140
|
-
::File.open(new_path, 'w') do |file|
|
141
|
-
file.chmod(0600)
|
142
|
-
file.write(encode_private_key(key))
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def new_source_key
|
147
|
-
@new_source_key ||= begin
|
148
|
-
if new_resource.source_key.is_a?(String)
|
149
|
-
source_key, source_key_format = Cheffish::KeyFormatter.decode(new_resource.source_key, new_resource.source_key_pass_phrase)
|
150
|
-
source_key
|
151
|
-
elsif new_resource.source_key
|
152
|
-
new_resource.source_key
|
153
|
-
elsif new_resource.source_key_path
|
154
|
-
source_key, source_key_format = Cheffish::KeyFormatter.decode(IO.read(new_resource.source_key_path), new_resource.source_key_pass_phrase, new_resource.source_key_path)
|
155
|
-
source_key
|
156
|
-
else
|
157
|
-
nil
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
attr_reader :current_private_key
|
163
|
-
|
164
|
-
def new_path
|
165
|
-
new_key_with_path[1]
|
166
|
-
end
|
167
|
-
|
168
|
-
def new_key_with_path
|
169
|
-
path = new_resource.path
|
170
|
-
if path.is_a?(Symbol)
|
171
|
-
return [ nil, path ]
|
172
|
-
elsif Pathname.new(path).relative?
|
173
|
-
private_key, private_key_path = Cheffish.get_private_key_with_path(path, run_context.config)
|
174
|
-
if private_key
|
175
|
-
return [ private_key, (private_key_path || :none) ]
|
176
|
-
elsif run_context.config[:private_key_write_path]
|
177
|
-
@should_create_directory = true
|
178
|
-
path = ::File.join(run_context.config[:private_key_write_path], path)
|
179
|
-
return [ nil, path ]
|
180
|
-
else
|
181
|
-
raise "Could not find key #{path} and Chef::Config.private_key_write_path is not set."
|
182
|
-
end
|
183
|
-
elsif ::File.exist?(path)
|
184
|
-
return [ IO.read(path), path ]
|
185
|
-
else
|
186
|
-
return [ nil, path ]
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
def load_current_resource
|
191
|
-
resource = Chef::Resource::PrivateKey.new(new_resource.name, run_context)
|
192
|
-
|
193
|
-
new_key, new_path = new_key_with_path
|
194
|
-
if new_path != :none && ::File.exist?(new_path)
|
195
|
-
resource.path new_path
|
196
|
-
@current_file_mode = ::File.stat(new_path).mode
|
197
|
-
else
|
198
|
-
resource.path :none
|
199
|
-
end
|
200
|
-
|
201
|
-
if new_key
|
202
|
-
begin
|
203
|
-
key, key_format = Cheffish::KeyFormatter.decode(new_key, new_resource.pass_phrase, new_path)
|
204
|
-
if key
|
205
|
-
@current_private_key = key
|
206
|
-
resource.format key_format[:format]
|
207
|
-
resource.type key_format[:type]
|
208
|
-
resource.size key_format[:size]
|
209
|
-
resource.exponent key_format[:exponent]
|
210
|
-
resource.pass_phrase key_format[:pass_phrase]
|
211
|
-
resource.cipher key_format[:cipher]
|
212
|
-
end
|
213
|
-
rescue
|
214
|
-
# If there's an error reading, we assume format and type are wrong and don't futz with them
|
215
|
-
Chef::Log.warn("Error reading #{new_path}: #{$!}")
|
216
|
-
end
|
217
|
-
else
|
218
|
-
resource.action :delete
|
219
|
-
end
|
220
|
-
|
221
|
-
@current_resource = resource
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
225
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
require 'chef/provider/lwrp_base'
|
2
|
-
require 'openssl'
|
3
|
-
require 'cheffish/key_formatter'
|
4
|
-
|
5
|
-
class Chef
|
6
|
-
class Provider
|
7
|
-
class PublicKey < Chef::Provider::LWRPBase
|
8
|
-
provides :public_key
|
9
|
-
|
10
|
-
action :create do
|
11
|
-
if !new_source_key
|
12
|
-
raise "No source key specified"
|
13
|
-
end
|
14
|
-
desired_output = encode_public_key(new_source_key)
|
15
|
-
if Array(current_resource.action) == [ :delete ] || desired_output != IO.read(new_resource.path)
|
16
|
-
converge_by "write #{new_resource.format} public key #{new_resource.path} from #{new_source_key_publicity} key #{new_resource.source_key_path}" do
|
17
|
-
IO.write(new_resource.path, desired_output)
|
18
|
-
# TODO permissions on file?
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
action :delete do
|
24
|
-
if Array(current_resource.action) == [ :create ]
|
25
|
-
converge_by "delete public key #{new_resource.path}" do
|
26
|
-
::File.unlink(new_resource.path)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def whyrun_supported?
|
32
|
-
true
|
33
|
-
end
|
34
|
-
|
35
|
-
def encode_public_key(key)
|
36
|
-
key_format = {}
|
37
|
-
key_format[:format] = new_resource.format if new_resource.format
|
38
|
-
Cheffish::KeyFormatter.encode(key, key_format)
|
39
|
-
end
|
40
|
-
|
41
|
-
attr_reader :current_public_key
|
42
|
-
attr_reader :new_source_key_publicity
|
43
|
-
|
44
|
-
def new_source_key
|
45
|
-
@new_source_key ||= begin
|
46
|
-
if new_resource.source_key.is_a?(String)
|
47
|
-
source_key, source_key_format = Cheffish::KeyFormatter.decode(new_resource.source_key, new_resource.source_key_pass_phrase)
|
48
|
-
elsif new_resource.source_key
|
49
|
-
source_key = new_resource.source_key
|
50
|
-
elsif new_resource.source_key_path
|
51
|
-
source_key, source_key_format = Cheffish::KeyFormatter.decode(IO.read(new_resource.source_key_path), new_resource.source_key_pass_phrase, new_resource.source_key_path)
|
52
|
-
else
|
53
|
-
return nil
|
54
|
-
end
|
55
|
-
|
56
|
-
if source_key.private?
|
57
|
-
@new_source_key_publicity = 'private'
|
58
|
-
source_key.public_key
|
59
|
-
else
|
60
|
-
@new_source_key_publicity = 'public'
|
61
|
-
source_key
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def load_current_resource
|
67
|
-
if ::File.exist?(new_resource.path)
|
68
|
-
resource = Chef::Resource::PublicKey.new(new_resource.path, run_context)
|
69
|
-
begin
|
70
|
-
key, key_format = Cheffish::KeyFormatter.decode(IO.read(new_resource.path), nil, new_resource.path)
|
71
|
-
if key
|
72
|
-
@current_public_key = key
|
73
|
-
resource.format key_format[:format]
|
74
|
-
end
|
75
|
-
rescue
|
76
|
-
# If there is an error reading we assume format and such is broken
|
77
|
-
end
|
78
|
-
|
79
|
-
@current_resource = resource
|
80
|
-
else
|
81
|
-
not_found_resource = Chef::Resource::PublicKey.new(new_resource.path, run_context)
|
82
|
-
not_found_resource.action :delete
|
83
|
-
@current_resource = not_found_resource
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|