cheffish 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +8 -8
- data/Rakefile +24 -12
- data/cheffish.gemspec +15 -15
- data/lib/chef/resource/chef_acl.rb +63 -63
- data/lib/chef/resource/chef_client.rb +9 -9
- data/lib/chef/resource/chef_container.rb +9 -9
- data/lib/chef/resource/chef_data_bag.rb +9 -9
- data/lib/chef/resource/chef_data_bag_item.rb +27 -27
- data/lib/chef/resource/chef_environment.rb +21 -22
- data/lib/chef/resource/chef_group.rb +19 -19
- data/lib/chef/resource/chef_mirror.rb +32 -17
- data/lib/chef/resource/chef_node.rb +14 -14
- data/lib/chef/resource/chef_organization.rb +29 -30
- data/lib/chef/resource/chef_resolved_cookbooks.rb +7 -7
- data/lib/chef/resource/chef_role.rb +25 -22
- data/lib/chef/resource/chef_user.rb +13 -14
- data/lib/chef/resource/private_key.rb +24 -25
- data/lib/chef/resource/public_key.rb +6 -7
- data/lib/cheffish.rb +17 -17
- data/lib/cheffish/array_property.rb +2 -2
- data/lib/cheffish/base_properties.rb +3 -3
- data/lib/cheffish/base_resource.rb +8 -8
- data/lib/cheffish/basic_chef_client.rb +17 -17
- data/lib/cheffish/chef_actor_base.rb +8 -8
- data/lib/cheffish/chef_run.rb +7 -2
- data/lib/cheffish/chef_run_data.rb +2 -2
- data/lib/cheffish/chef_run_listener.rb +1 -1
- data/lib/cheffish/key_formatter.rb +16 -18
- data/lib/cheffish/merged_config.rb +5 -3
- data/lib/cheffish/node_properties.rb +11 -7
- data/lib/cheffish/recipe_dsl.rb +33 -34
- data/lib/cheffish/rspec.rb +3 -3
- data/lib/cheffish/rspec/chef_run_support.rb +13 -13
- data/lib/cheffish/rspec/matchers.rb +4 -4
- data/lib/cheffish/rspec/matchers/be_idempotent.rb +3 -3
- data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +3 -3
- data/lib/cheffish/rspec/matchers/have_updated.rb +3 -3
- data/lib/cheffish/rspec/recipe_run_wrapper.rb +8 -7
- data/lib/cheffish/rspec/repository_support.rb +6 -6
- data/lib/cheffish/server_api.rb +11 -11
- data/lib/cheffish/version.rb +1 -1
- data/spec/functional/fingerprint_spec.rb +12 -12
- data/spec/functional/merged_config_spec.rb +46 -6
- data/spec/functional/server_api_spec.rb +3 -3
- data/spec/integration/chef_acl_spec.rb +489 -489
- data/spec/integration/chef_client_spec.rb +39 -39
- data/spec/integration/chef_container_spec.rb +14 -14
- data/spec/integration/chef_data_bag_item_spec.rb +9 -9
- data/spec/integration/chef_group_spec.rb +219 -219
- data/spec/integration/chef_mirror_spec.rb +228 -228
- data/spec/integration/chef_node_spec.rb +511 -511
- data/spec/integration/chef_organization_spec.rb +126 -126
- data/spec/integration/chef_role_spec.rb +33 -33
- data/spec/integration/chef_user_spec.rb +37 -37
- data/spec/integration/private_key_spec.rb +154 -154
- data/spec/integration/recipe_dsl_spec.rb +10 -10
- data/spec/integration/rspec/converge_spec.rb +49 -49
- data/spec/support/key_support.rb +6 -6
- data/spec/support/spec_support.rb +3 -3
- data/spec/unit/get_private_key_spec.rb +19 -19
- data/spec/unit/recipe_run_wrapper_spec.rb +4 -4
- metadata +3 -3
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "openssl/cipher"
|
2
|
+
require "cheffish/base_resource"
|
3
|
+
require "openssl"
|
4
|
+
require "cheffish/key_formatter"
|
5
5
|
|
6
6
|
class Chef
|
7
7
|
class Resource
|
@@ -23,7 +23,6 @@ class Chef
|
|
23
23
|
Chef::Log.debug("Overloading #{resource_name}.load_prior_resource with NOOP")
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
26
|
action :create do
|
28
27
|
if !new_source_key
|
29
28
|
raise "No source key specified"
|
@@ -68,10 +67,10 @@ class Chef
|
|
68
67
|
end
|
69
68
|
|
70
69
|
if source_key.private?
|
71
|
-
@new_source_key_publicity =
|
70
|
+
@new_source_key_publicity = "private"
|
72
71
|
source_key.public_key
|
73
72
|
else
|
74
|
-
@new_source_key_publicity =
|
73
|
+
@new_source_key_publicity = "public"
|
75
74
|
source_key
|
76
75
|
end
|
77
76
|
end
|
data/lib/cheffish.rb
CHANGED
@@ -10,8 +10,8 @@ module Cheffish
|
|
10
10
|
:chef_server_url => config[:chef_server_url],
|
11
11
|
:options => {
|
12
12
|
:client_name => config[:node_name],
|
13
|
-
:signing_key_filename => config[:client_key]
|
14
|
-
}
|
13
|
+
:signing_key_filename => config[:client_key],
|
14
|
+
},
|
15
15
|
}
|
16
16
|
end
|
17
17
|
|
@@ -19,7 +19,7 @@ module Cheffish
|
|
19
19
|
# Pin the server api version to 0 until https://github.com/chef/cheffish/issues/56
|
20
20
|
# gets the correct compatibility fix.
|
21
21
|
chef_server[:options] ||= {}
|
22
|
-
chef_server[:options]
|
22
|
+
chef_server[:options][:api_version] = "0"
|
23
23
|
Cheffish::ServerAPI.new(chef_server[:chef_server_url], chef_server[:options])
|
24
24
|
end
|
25
25
|
|
@@ -32,7 +32,7 @@ module Cheffish
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def self.load_chef_config(chef_config = Chef::Config)
|
35
|
-
if ::Gem::Version.new(::Chef::VERSION) >= ::Gem::Version.new(
|
35
|
+
if ::Gem::Version.new(::Chef::VERSION) >= ::Gem::Version.new("12.0.0")
|
36
36
|
chef_config.config_file = ::Chef::Knife.chef_config_dir
|
37
37
|
else
|
38
38
|
chef_config.config_file = ::Chef::Knife.locate_config_file
|
@@ -50,7 +50,7 @@ module Cheffish
|
|
50
50
|
rescue Exception => error
|
51
51
|
Chef::Log.fatal("Configuration error #{error.class}: #{error.message}")
|
52
52
|
filtered_trace = error.backtrace.grep(/#{Regexp.escape(config_file_path)}/)
|
53
|
-
filtered_trace.each {|line| Chef::Log.fatal(" " + line )}
|
53
|
+
filtered_trace.each { |line| Chef::Log.fatal(" " + line ) }
|
54
54
|
Chef::Application.fatal!("Aborting due to error in '#{config_file_path}'", 2)
|
55
55
|
end
|
56
56
|
end
|
@@ -65,7 +65,7 @@ module Cheffish
|
|
65
65
|
Chef::Config.chef_repo_path = Chef::Config.find_chef_repo_path(Dir.pwd)
|
66
66
|
end
|
67
67
|
begin
|
68
|
-
require
|
68
|
+
require "chef/local_mode"
|
69
69
|
Chef::LocalMode.with_server_connectivity(&block)
|
70
70
|
|
71
71
|
rescue LoadError
|
@@ -100,8 +100,8 @@ module Cheffish
|
|
100
100
|
next unless File.exist?(private_key_path)
|
101
101
|
Dir.entries(private_key_path).sort.each do |key|
|
102
102
|
ext = File.extname(key)
|
103
|
-
if key == name || ext ==
|
104
|
-
key_name = key[0..-(ext.length+1)]
|
103
|
+
if key == name || ext == "" || ext == ".pem"
|
104
|
+
key_name = key[0..-(ext.length + 1)]
|
105
105
|
if key_name == name || key == name
|
106
106
|
Chef::Log.info("Reading key #{name} from file #{private_key_path}/#{key}")
|
107
107
|
return [ IO.read("#{private_key_path}/#{key}"), "#{private_key_path}/#{key}" ]
|
@@ -120,12 +120,12 @@ end
|
|
120
120
|
|
121
121
|
# Include all recipe objects so require 'cheffish' brings in the whole recipe DSL
|
122
122
|
|
123
|
-
require
|
124
|
-
require
|
125
|
-
require
|
126
|
-
require
|
127
|
-
require
|
128
|
-
require
|
129
|
-
require
|
130
|
-
require
|
131
|
-
require
|
123
|
+
require "chef/run_list/run_list_item"
|
124
|
+
require "cheffish/basic_chef_client"
|
125
|
+
require "cheffish/server_api"
|
126
|
+
require "chef/knife"
|
127
|
+
require "chef/config_fetcher"
|
128
|
+
require "chef/log"
|
129
|
+
require "chef/application"
|
130
|
+
require "cheffish/recipe_dsl"
|
131
|
+
require "cheffish/node_properties"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "chef/property"
|
2
2
|
|
3
3
|
module Cheffish
|
4
4
|
# A typical array property. Defaults to [], accepts multiple args to setter, accumulates values.
|
@@ -12,7 +12,7 @@ module Cheffish
|
|
12
12
|
|
13
13
|
# Support my_property 'a', 'b', 'c'; my_property 'a'; and my_property ['a', 'b']
|
14
14
|
def emit_dsl
|
15
|
-
declared_in.class_eval(<<-EOM, __FILE__, __LINE__+1)
|
15
|
+
declared_in.class_eval(<<-EOM, __FILE__, __LINE__ + 1)
|
16
16
|
def #{name}(*values)
|
17
17
|
property = self.class.properties[#{name.inspect}]
|
18
18
|
if values.empty?
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "chef/resource"
|
2
|
+
require "cheffish/base_properties"
|
3
3
|
|
4
4
|
module Cheffish
|
5
5
|
class BaseResource < Chef::Resource
|
@@ -84,7 +84,7 @@ module Cheffish
|
|
84
84
|
data_handler.normalize(json, fake_entry)
|
85
85
|
end
|
86
86
|
|
87
|
-
def json_differences(old_json, new_json, print_values=true, name =
|
87
|
+
def json_differences(old_json, new_json, print_values = true, name = "", result = nil)
|
88
88
|
result ||= []
|
89
89
|
json_differences_internal(old_json, new_json, print_values, name, result)
|
90
90
|
result
|
@@ -97,7 +97,7 @@ module Cheffish
|
|
97
97
|
if old_json.has_key?(new_key)
|
98
98
|
removed_keys.delete(new_key)
|
99
99
|
if new_value != old_json[new_key]
|
100
|
-
json_differences_internal(old_json[new_key], new_value, print_values, name ==
|
100
|
+
json_differences_internal(old_json[new_key], new_value, print_values, name == "" ? new_key : "#{name}.#{new_key}", result)
|
101
101
|
end
|
102
102
|
else
|
103
103
|
if print_values
|
@@ -136,11 +136,11 @@ module Cheffish
|
|
136
136
|
modifiers.each do |path, value|
|
137
137
|
path = [path] if !path.kind_of?(Array)
|
138
138
|
path = path.map { |path_part| path_part.to_s }
|
139
|
-
parent = 0.upto(path.size-2).inject(json) do |hash, index|
|
139
|
+
parent = 0.upto(path.size - 2).inject(json) do |hash, index|
|
140
140
|
if hash.nil?
|
141
141
|
nil
|
142
142
|
elsif !hash.is_a?(Hash)
|
143
|
-
raise "Attempt to set #{path} to #{value} when #{path[0..index-1]} is not a hash"
|
143
|
+
raise "Attempt to set #{path} to #{value} when #{path[0..index - 1]} is not a hash"
|
144
144
|
else
|
145
145
|
hash[path[index]]
|
146
146
|
end
|
@@ -181,7 +181,7 @@ module Cheffish
|
|
181
181
|
result = []
|
182
182
|
add_to_run_list_index = 0
|
183
183
|
run_list_index = 0
|
184
|
-
while run_list_index < run_list.run_list_items.size
|
184
|
+
while run_list_index < run_list.run_list_items.size
|
185
185
|
# See if the desired run list has this item
|
186
186
|
found_desired = add_to_run_list.index { |item| same_run_list_item(item, run_list[run_list_index]) }
|
187
187
|
if found_desired
|
@@ -192,7 +192,7 @@ module Cheffish
|
|
192
192
|
# be X, A, B, Y, Z.
|
193
193
|
if found_desired >= add_to_run_list_index
|
194
194
|
result += add_to_run_list[add_to_run_list_index..found_desired].map { |item| item.to_s }
|
195
|
-
add_to_run_list_index = found_desired+1
|
195
|
+
add_to_run_list_index = found_desired + 1
|
196
196
|
end
|
197
197
|
else
|
198
198
|
# If not, just copy it in
|
@@ -1,13 +1,13 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
1
|
+
require "cheffish/version"
|
2
|
+
require "chef/dsl/recipe"
|
3
|
+
require "chef/event_dispatch/base"
|
4
|
+
require "chef/event_dispatch/dispatcher"
|
5
|
+
require "chef/node"
|
6
|
+
require "chef/run_context"
|
7
|
+
require "chef/runner"
|
8
|
+
require "forwardable"
|
9
|
+
require "chef/providers"
|
10
|
+
require "chef/resources"
|
11
11
|
|
12
12
|
module Cheffish
|
13
13
|
class BasicChefClient
|
@@ -16,8 +16,8 @@ module Cheffish
|
|
16
16
|
def initialize(node = nil, events = nil, **chef_config)
|
17
17
|
if !node
|
18
18
|
node = Chef::Node.new
|
19
|
-
node.name
|
20
|
-
node.automatic[:platform] =
|
19
|
+
node.name "basic_chef_client"
|
20
|
+
node.automatic[:platform] = "basic_chef_client"
|
21
21
|
node.automatic[:platform_version] = Cheffish::VERSION
|
22
22
|
end
|
23
23
|
|
@@ -25,7 +25,7 @@ module Cheffish
|
|
25
25
|
@chef_config = chef_config
|
26
26
|
|
27
27
|
with_chef_config do
|
28
|
-
@cookbook_name =
|
28
|
+
@cookbook_name = "basic_chef_client"
|
29
29
|
@event_catcher = BasicChefClientEvents.new
|
30
30
|
dispatcher = Chef::EventDispatch::Dispatcher.new(@event_catcher)
|
31
31
|
case events
|
@@ -37,7 +37,7 @@ module Cheffish
|
|
37
37
|
end
|
38
38
|
@run_context = Chef::RunContext.new(node, {}, dispatcher)
|
39
39
|
@updated = []
|
40
|
-
@cookbook_name =
|
40
|
+
@cookbook_name = "basic_chef_client"
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -58,7 +58,7 @@ module Cheffish
|
|
58
58
|
|
59
59
|
def load_block(&block)
|
60
60
|
with_chef_config do
|
61
|
-
@recipe_name =
|
61
|
+
@recipe_name = "block"
|
62
62
|
instance_eval(&block)
|
63
63
|
end
|
64
64
|
end
|
@@ -79,7 +79,7 @@ module Cheffish
|
|
79
79
|
|
80
80
|
# Builds a resource sans context, which can be later used in a new client's
|
81
81
|
# add_resource() method.
|
82
|
-
def self.build_resource(type, name, created_at=nil, &resource_attrs_block)
|
82
|
+
def self.build_resource(type, name, created_at = nil, &resource_attrs_block)
|
83
83
|
created_at ||= caller[0]
|
84
84
|
result = BasicChefClient.new.tap do |client|
|
85
85
|
client.with_chef_config do
|
@@ -129,7 +129,7 @@ module Cheffish
|
|
129
129
|
# end
|
130
130
|
begin
|
131
131
|
deep_merge_config(chef_config, Chef::Config)
|
132
|
-
|
132
|
+
yield
|
133
133
|
ensure
|
134
134
|
# $stdout = old_stdout if chef_config[:stdout]
|
135
135
|
# $stderr = old_stderr if chef_config[:stderr]
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "cheffish/key_formatter"
|
2
|
+
require "cheffish/base_resource"
|
3
3
|
|
4
4
|
module Cheffish
|
5
5
|
class ChefActorBase < Cheffish::BaseResource
|
@@ -11,7 +11,7 @@ module Cheffish
|
|
11
11
|
end
|
12
12
|
|
13
13
|
# Create or update the client/user
|
14
|
-
current_public_key = new_json[
|
14
|
+
current_public_key = new_json["public_key"]
|
15
15
|
differences = json_differences(current_json, new_json)
|
16
16
|
if current_resource_exists?
|
17
17
|
# Update the actor if it's different
|
@@ -19,7 +19,7 @@ module Cheffish
|
|
19
19
|
description = [ "update #{actor_type} #{new_resource.name} at #{actor_path}" ] + differences
|
20
20
|
converge_by description do
|
21
21
|
result = rest.put("#{actor_path}/#{new_resource.name}", normalize_for_put(new_json))
|
22
|
-
current_public_key, current_public_key_format = Cheffish::KeyFormatter.decode(result[
|
22
|
+
current_public_key, current_public_key_format = Cheffish::KeyFormatter.decode(result["public_key"]) if result["public_key"]
|
23
23
|
end
|
24
24
|
end
|
25
25
|
else
|
@@ -30,7 +30,7 @@ module Cheffish
|
|
30
30
|
description = [ "create #{actor_type} #{new_resource.name} at #{actor_path}" ] + differences
|
31
31
|
converge_by description do
|
32
32
|
result = rest.post("#{actor_path}", normalize_for_post(new_json))
|
33
|
-
current_public_key, current_public_key_format = Cheffish::KeyFormatter.decode(result[
|
33
|
+
current_public_key, current_public_key_format = Cheffish::KeyFormatter.decode(result["public_key"]) if result["public_key"]
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -39,9 +39,9 @@ module Cheffish
|
|
39
39
|
# TODO use inline_resource
|
40
40
|
key_content = Cheffish::KeyFormatter.encode(current_public_key, { :format => new_resource.output_key_format })
|
41
41
|
if !current_resource.output_key_path
|
42
|
-
action =
|
42
|
+
action = "create"
|
43
43
|
elsif key_content != IO.read(current_resource.output_key_path)
|
44
|
-
action =
|
44
|
+
action = "overwrite"
|
45
45
|
else
|
46
46
|
action = nil
|
47
47
|
end
|
@@ -109,7 +109,7 @@ module Cheffish
|
|
109
109
|
|
110
110
|
def augment_new_json(json)
|
111
111
|
if new_public_key
|
112
|
-
json[
|
112
|
+
json["public_key"] = new_public_key.to_pem
|
113
113
|
end
|
114
114
|
json
|
115
115
|
end
|
data/lib/cheffish/chef_run.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "cheffish/basic_chef_client"
|
2
2
|
|
3
3
|
module Cheffish
|
4
4
|
class ChefRun
|
@@ -11,7 +11,7 @@ module Cheffish
|
|
11
11
|
# - log_location: <path|IO object> - where to stream logs to
|
12
12
|
# - verbose_logging: true|false - true if you want verbose logging in :debug
|
13
13
|
#
|
14
|
-
def initialize(chef_config={})
|
14
|
+
def initialize(chef_config = {})
|
15
15
|
@chef_config = chef_config || {}
|
16
16
|
end
|
17
17
|
|
@@ -56,18 +56,23 @@ module Cheffish
|
|
56
56
|
def stdout
|
57
57
|
@client ? client.chef_config[:stdout].string : nil
|
58
58
|
end
|
59
|
+
|
59
60
|
def stderr
|
60
61
|
@client ? client.chef_config[:stderr].string : nil
|
61
62
|
end
|
63
|
+
|
62
64
|
def logs
|
63
65
|
@client ? client.chef_config[:log_location].string : nil
|
64
66
|
end
|
67
|
+
|
65
68
|
def logged_warnings
|
66
69
|
logs.lines.select { |l| l =~ /^\[[^\]]*\] WARN:/ }.join("\n")
|
67
70
|
end
|
71
|
+
|
68
72
|
def logged_errors
|
69
73
|
logs.lines.select { |l| l =~ /^\[[^\]]*\] ERROR:/ }.join("\n")
|
70
74
|
end
|
75
|
+
|
71
76
|
def logged_info
|
72
77
|
logs.lines.select { |l| l =~ /^\[[^\]]*\] INFO:/ }.join("\n")
|
73
78
|
end
|
@@ -1,14 +1,14 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
1
|
+
require "openssl"
|
2
|
+
require "net/ssh"
|
3
|
+
require "etc"
|
4
|
+
require "socket"
|
5
|
+
require "digest/md5"
|
6
|
+
require "base64"
|
7
7
|
|
8
8
|
module Cheffish
|
9
9
|
class KeyFormatter
|
10
10
|
# Returns nil or key, format
|
11
|
-
def self.decode(str, pass_phrase=nil, filename=
|
11
|
+
def self.decode(str, pass_phrase = nil, filename = "")
|
12
12
|
key_format = {}
|
13
13
|
key_format[:format] = format_of(str)
|
14
14
|
|
@@ -38,7 +38,7 @@ module Cheffish
|
|
38
38
|
encode_openssh_key(key)
|
39
39
|
when :pem
|
40
40
|
if key_format[:pass_phrase]
|
41
|
-
cipher = key_format[:cipher] ||
|
41
|
+
cipher = key_format[:cipher] || "DES-EDE3-CBC"
|
42
42
|
key.to_pem(OpenSSL::Cipher.new(cipher), key_format[:pass_phrase])
|
43
43
|
else
|
44
44
|
key.to_pem
|
@@ -48,44 +48,42 @@ module Cheffish
|
|
48
48
|
when :fingerprint, :pkcs1md5fingerprint
|
49
49
|
hexes = Digest::MD5.hexdigest(key.to_der)
|
50
50
|
# Put : between every pair of hexes
|
51
|
-
hexes.scan(/../).join(
|
51
|
+
hexes.scan(/../).join(":")
|
52
52
|
when :rfc4716md5fingerprint
|
53
53
|
type, base64_data, etc = encode_openssh_key(key).split
|
54
54
|
data = Base64.decode64(base64_data)
|
55
55
|
hexes = Digest::MD5.hexdigest(data)
|
56
|
-
hexes.scan(/../).join(
|
56
|
+
hexes.scan(/../).join(":")
|
57
57
|
when :pkcs8sha1fingerprint
|
58
58
|
if RUBY_VERSION.to_f >= 2.0
|
59
59
|
raise "PKCS8 SHA1 not supported in Ruby #{RUBY_VERSION}"
|
60
60
|
end
|
61
|
-
require
|
61
|
+
require "openssl_pkcs8"
|
62
62
|
pkcs8_pem = key.to_pem_pkcs8
|
63
63
|
pkcs8_base64 = pkcs8_pem.split("\n").reject { |l| l =~ /^-----/ }
|
64
64
|
pkcs8_data = Base64.decode64(pkcs8_base64.join)
|
65
65
|
hexes = Digest::SHA1.hexdigest(pkcs8_data)
|
66
|
-
hexes.scan(/../).join(
|
66
|
+
hexes.scan(/../).join(":")
|
67
67
|
else
|
68
68
|
raise "Unrecognized key format #{format}"
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
private
|
73
|
-
|
74
72
|
def self.encode_openssh_key(key)
|
75
73
|
# TODO there really isn't a method somewhere in net/ssh or openssl that does this??
|
76
74
|
type = key.ssh_type
|
77
|
-
data = [ key.to_blob ].pack(
|
75
|
+
data = [ key.to_blob ].pack("m0")
|
78
76
|
"#{type} #{data} #{Etc.getlogin}@#{Socket.gethostname}"
|
79
77
|
end
|
80
78
|
|
81
|
-
def self.decode_openssh_key(str, filename=
|
79
|
+
def self.decode_openssh_key(str, filename = "")
|
82
80
|
Net::SSH::KeyFactory.load_data_public_key(str, filename)
|
83
81
|
end
|
84
82
|
|
85
83
|
def self.format_of(key_contents)
|
86
|
-
if key_contents.start_with?(
|
84
|
+
if key_contents.start_with?("-----BEGIN ")
|
87
85
|
:pem
|
88
|
-
elsif key_contents.start_with?(
|
86
|
+
elsif key_contents.start_with?("ssh-rsa ", "ssh-dss ")
|
89
87
|
:openssh
|
90
88
|
else
|
91
89
|
:der
|