chef-encrypted-attributes 0.1.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 +7 -0
- data/API.md +163 -0
- data/CHANGELOG.md +7 -0
- data/INTERNAL.md +111 -0
- data/LICENSE +190 -0
- data/README.md +330 -0
- data/Rakefile +46 -0
- data/TESTING.md +45 -0
- data/TODO.md +20 -0
- data/lib/chef-encrypted-attributes.rb +19 -0
- data/lib/chef/encrypted_attribute.rb +218 -0
- data/lib/chef/encrypted_attribute/cache_lru.rb +74 -0
- data/lib/chef/encrypted_attribute/config.rb +200 -0
- data/lib/chef/encrypted_attribute/encrypted_mash.rb +122 -0
- data/lib/chef/encrypted_attribute/encrypted_mash/version0.rb +143 -0
- data/lib/chef/encrypted_attribute/encrypted_mash/version1.rb +140 -0
- data/lib/chef/encrypted_attribute/exceptions.rb +38 -0
- data/lib/chef/encrypted_attribute/local_node.rb +38 -0
- data/lib/chef/encrypted_attribute/remote_clients.rb +46 -0
- data/lib/chef/encrypted_attribute/remote_node.rb +111 -0
- data/lib/chef/encrypted_attribute/remote_users.rb +73 -0
- data/lib/chef/encrypted_attribute/search_helper.rb +144 -0
- data/lib/chef/encrypted_attribute/version.rb +23 -0
- data/lib/chef/knife/core/config.rb +19 -0
- data/lib/chef/knife/core/encrypted_attribute_editor_options.rb +100 -0
- data/lib/chef/knife/encrypted_attribute_create.rb +67 -0
- data/lib/chef/knife/encrypted_attribute_delete.rb +71 -0
- data/lib/chef/knife/encrypted_attribute_edit.rb +68 -0
- data/lib/chef/knife/encrypted_attribute_show.rb +86 -0
- data/lib/chef/knife/encrypted_attribute_update.rb +65 -0
- data/spec/benchmark_helper.rb +32 -0
- data/spec/integration_helper.rb +20 -0
- data/spec/spec_helper.rb +38 -0
- metadata +204 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
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/encrypted_attribute/search_helper'
|
20
|
+
require 'chef/encrypted_attribute/cache_lru'
|
21
|
+
|
22
|
+
class Chef
|
23
|
+
class EncryptedAttribute
|
24
|
+
class RemoteClients
|
25
|
+
extend ::Chef::EncryptedAttribute::SearchHelper
|
26
|
+
|
27
|
+
def self.cache
|
28
|
+
@@cache ||= Chef::EncryptedAttribute::CacheLru.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.get_public_keys(search='*:*', partial_search=true)
|
32
|
+
escaped_query = escape_query(search)
|
33
|
+
if cache.has_key?(escaped_query)
|
34
|
+
cache[escaped_query]
|
35
|
+
else
|
36
|
+
cache[escaped_query] = search(:client, search, {
|
37
|
+
'public_key' => [ 'public_key' ]
|
38
|
+
}, 1000, partial_search).map do |client|
|
39
|
+
client['public_key']
|
40
|
+
end.compact
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
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/mixin/params_validate'
|
20
|
+
require 'chef/encrypted_attribute/search_helper'
|
21
|
+
require 'chef/encrypted_attribute/cache_lru'
|
22
|
+
|
23
|
+
class Chef
|
24
|
+
class EncryptedAttribute
|
25
|
+
class RemoteNode
|
26
|
+
include ::Chef::Mixin::ParamsValidate
|
27
|
+
include ::Chef::EncryptedAttribute::SearchHelper
|
28
|
+
|
29
|
+
def initialize(name)
|
30
|
+
name(name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.cache
|
34
|
+
@@cache ||= Chef::EncryptedAttribute::CacheLru.new(0) # disabled by default
|
35
|
+
end
|
36
|
+
|
37
|
+
def name(arg=nil)
|
38
|
+
set_or_return(
|
39
|
+
:name,
|
40
|
+
arg,
|
41
|
+
:kind_of => String
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_attribute(attr_ary, partial_search=true)
|
46
|
+
unless attr_ary.kind_of?(Array)
|
47
|
+
raise ArgumentError, "#{self.class.to_s}##{__method__} attr_ary argument must be an array of strings. You passed #{attr_ary.inspect}."
|
48
|
+
end
|
49
|
+
cache_key = cache_key(name, attr_ary)
|
50
|
+
if self.class.cache.has_key?(cache_key)
|
51
|
+
self.class.cache[cache_key]
|
52
|
+
else
|
53
|
+
keys = { 'value' => attr_ary }
|
54
|
+
res = search(:node, "name:#{@name}", keys, 1, partial_search)
|
55
|
+
self.class.cache[cache_key] = if res.kind_of?(Array) and
|
56
|
+
res[0].kind_of?(Hash) and res[0].has_key?('value')
|
57
|
+
res[0]['value']
|
58
|
+
else
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def save_attribute(attr_ary, value)
|
65
|
+
unless attr_ary.kind_of?(Array)
|
66
|
+
raise ArgumentError, "#{self.class.to_s}##{__method__} attr_ary argument must be an array of strings. You passed #{attr_ary.inspect}."
|
67
|
+
end
|
68
|
+
cache_key = cache_key(name, attr_ary)
|
69
|
+
|
70
|
+
node = Chef::Node.load(name)
|
71
|
+
last = attr_ary.pop
|
72
|
+
node_attr = attr_ary.reduce(node.normal) do |a, k|
|
73
|
+
a[k] = Mash.new unless a.has_key?(k)
|
74
|
+
a[k]
|
75
|
+
end
|
76
|
+
node_attr[last] = value
|
77
|
+
|
78
|
+
node.save
|
79
|
+
self.class.cache[cache_key] = value
|
80
|
+
end
|
81
|
+
|
82
|
+
def delete_attribute(attr_ary)
|
83
|
+
unless attr_ary.kind_of?(Array)
|
84
|
+
raise ArgumentError, "#{self.class.to_s}##{__method__} attr_ary argument must be an array of strings. You passed #{attr_ary.inspect}."
|
85
|
+
end
|
86
|
+
cache_key = cache_key(name, attr_ary)
|
87
|
+
|
88
|
+
node = Chef::Node.load(name)
|
89
|
+
last = attr_ary.pop
|
90
|
+
node_attr = attr_ary.reduce(node.normal) do |a, k|
|
91
|
+
a.respond_to?(:has_key?) && a.has_key?(k) ? a[k] : nil
|
92
|
+
end
|
93
|
+
if node_attr.respond_to?(:has_key?) && node_attr.has_key?(last)
|
94
|
+
node_attr.delete(last)
|
95
|
+
node.save
|
96
|
+
self.class.cache.delete(cache_key)
|
97
|
+
true
|
98
|
+
else
|
99
|
+
false
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
def cache_key(name, attr_ary)
|
106
|
+
"#{name}:#{attr_ary.inspect}" # TODO ok, this can be improved
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
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/user'
|
20
|
+
require 'chef/encrypted_attribute/exceptions'
|
21
|
+
require 'chef/encrypted_attribute/cache_lru'
|
22
|
+
|
23
|
+
class Chef
|
24
|
+
class EncryptedAttribute
|
25
|
+
class RemoteUsers
|
26
|
+
|
27
|
+
def self.cache
|
28
|
+
@@cache ||= Chef::EncryptedAttribute::CacheLru.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.get_public_keys(users=[])
|
32
|
+
if users == '*' # users are [a-z0-9\-_]+, cannot be *
|
33
|
+
if cache.has_key?('*')
|
34
|
+
cache['*']
|
35
|
+
else
|
36
|
+
cache['*'] = get_all_public_keys
|
37
|
+
end
|
38
|
+
elsif users.kind_of?(Array)
|
39
|
+
get_users_public_keys(users)
|
40
|
+
elsif not users.nil?
|
41
|
+
raise ArgumentError, "#{self.class.to_s}##{__method__} users argument must be an array or \"*\"."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
def self.get_user_public_key(name)
|
48
|
+
return cache[name] if cache.has_key?(name)
|
49
|
+
user = Chef::User.load(name)
|
50
|
+
cache[name] = user.public_key
|
51
|
+
rescue Net::HTTPServerException => e
|
52
|
+
case e.response.code
|
53
|
+
when '403'
|
54
|
+
raise InsufficientPrivileges, 'Your node needs admin privileges to be able to work with Chef Users.'
|
55
|
+
when '404' # Not Found
|
56
|
+
raise UserNotFound, "Chef User not found: \"#{name}\"."
|
57
|
+
else
|
58
|
+
raise e
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.get_users_public_keys(users)
|
63
|
+
users.map { |n| get_user_public_key(n) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.get_all_public_keys
|
67
|
+
# Chef::User.list(inflate=true) has a bug
|
68
|
+
get_users_public_keys(Chef::User.list.keys)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
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/search/query'
|
20
|
+
require 'chef/encrypted_attribute/exceptions'
|
21
|
+
|
22
|
+
class Chef
|
23
|
+
class EncryptedAttribute
|
24
|
+
module SearchHelper
|
25
|
+
extend self
|
26
|
+
|
27
|
+
def query
|
28
|
+
Chef::Search::Query.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def escape(str)
|
32
|
+
URI.escape(str.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
33
|
+
end
|
34
|
+
|
35
|
+
def escape_query(query)
|
36
|
+
query_s = if query.kind_of?(Array)
|
37
|
+
query.map do |item|
|
38
|
+
"( #{item} )"
|
39
|
+
end.compact.join(' OR ')
|
40
|
+
else
|
41
|
+
query.to_s
|
42
|
+
end
|
43
|
+
escape(query_s)
|
44
|
+
end
|
45
|
+
|
46
|
+
def valid_search_keys?(keys)
|
47
|
+
return false unless keys.kind_of?(Hash)
|
48
|
+
keys.reduce(true) do |r, (k, v)|
|
49
|
+
r && unless k.kind_of?(String) || k.kind_of?(Symbol) and v.kind_of?(Array)
|
50
|
+
false
|
51
|
+
else
|
52
|
+
v.reduce(true) do |r, x|
|
53
|
+
r and x.kind_of?(String)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def empty_search?(query)
|
60
|
+
query.kind_of?(String) && query.empty? or
|
61
|
+
query.kind_of?(Array) && query.count == 0
|
62
|
+
end
|
63
|
+
|
64
|
+
def search(type, query, keys, rows=1000, partial_search=true)
|
65
|
+
return [] if empty_search?(query) # avoid empty searches
|
66
|
+
if partial_search
|
67
|
+
partial_search(type, query, keys, rows)
|
68
|
+
else
|
69
|
+
normal_search(type, query, keys, rows)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def normal_search(type, query, keys, rows=1000)
|
74
|
+
escaped_query = escape_query(query)
|
75
|
+
Chef::Log.info("Normal Search query: #{escaped_query}, keys: #{keys.inspect}")
|
76
|
+
unless valid_search_keys?(keys)
|
77
|
+
raise InvalidSearchKeys, "Invalid search keys: #{keys.inspect}"
|
78
|
+
end
|
79
|
+
|
80
|
+
begin
|
81
|
+
resp = self.query.search(type, escaped_query, nil, 0, rows)[0]
|
82
|
+
rescue Net::HTTPServerException => e
|
83
|
+
if e.response.kind_of?(Net::HTTPResponse) and e.response.code == '404' # Not Found
|
84
|
+
return []
|
85
|
+
else
|
86
|
+
raise SearchFailure, "Partial Search exception #{e.class.name}: #{e.to_s}"
|
87
|
+
end
|
88
|
+
rescue Net::HTTPFatalError => e
|
89
|
+
raise SearchFailure, "Normal Search exception #{e.class.name}: #{e.to_s}"
|
90
|
+
end
|
91
|
+
unless resp.kind_of?(Array)
|
92
|
+
raise SearchFatalError, "Wrong response received from Normal Search: #{resp.inspect}"
|
93
|
+
end
|
94
|
+
# TODO too complex, refactorize
|
95
|
+
resp.map do |row|
|
96
|
+
Hash[keys.map do |key_name, attr_ary|
|
97
|
+
value = attr_ary.reduce(row) do |r, attr|
|
98
|
+
if r.respond_to?(attr.to_sym)
|
99
|
+
r.send(attr.to_sym)
|
100
|
+
elsif r.respond_to?(:has_key?)
|
101
|
+
if r.has_key?(attr.to_s)
|
102
|
+
r[attr.to_s]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
[ key_name, value ]
|
107
|
+
end]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def partial_search(type, query, keys, rows=1000)
|
112
|
+
escaped_query = "search/#{escape(type)}?q=#{escape_query(query)}&start=0&rows=#{rows}"
|
113
|
+
Chef::Log.info("Partial Search query: #{escaped_query}, keys: #{keys.inspect}")
|
114
|
+
unless valid_search_keys?(keys)
|
115
|
+
raise InvalidSearchKeys, "Invalid search keys: #{keys.inspect}"
|
116
|
+
end
|
117
|
+
|
118
|
+
rest = Chef::REST.new(Chef::Config[:chef_server_url])
|
119
|
+
begin
|
120
|
+
resp = rest.post_rest(escaped_query, keys)
|
121
|
+
rescue Net::HTTPServerException => e
|
122
|
+
if e.response.kind_of?(Net::HTTPResponse) and e.response.code == '404' # Not Found
|
123
|
+
return []
|
124
|
+
else
|
125
|
+
raise SearchFailure, "Partial Search exception #{e.class.name}: #{e.to_s}"
|
126
|
+
end
|
127
|
+
rescue Net::HTTPFatalError => e
|
128
|
+
raise SearchFailure, "Partial Search exception #{e.class.name}: #{e.to_s}"
|
129
|
+
end
|
130
|
+
unless resp.kind_of?(Hash) and resp.has_key?('rows') and resp['rows'].kind_of?(Array)
|
131
|
+
raise SearchFatalError, "Wrong response received from Partial Search: #{resp.inspect}"
|
132
|
+
end
|
133
|
+
resp['rows'].map do |row|
|
134
|
+
if row.kind_of?(Hash) and row['data'].kind_of?(Hash)
|
135
|
+
row['data']
|
136
|
+
else
|
137
|
+
raise SearchFatalError, "Wrong row format received from Partial Search: #{row.inspect}"
|
138
|
+
end
|
139
|
+
end.compact
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
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
|
+
class Chef
|
20
|
+
class EncryptedAttribute
|
21
|
+
VERSION = '0.1.0'
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
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
|
+
Chef::Config[:knife][:encrypted_attributes] = Mash.new unless Chef::Config[:knife][:encrypted_attributes].kind_of?(Hash)
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
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/knife/core/config'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
module Core
|
24
|
+
|
25
|
+
module EncryptedAttributeEditorOptions
|
26
|
+
def self.included(includer)
|
27
|
+
includer.class_eval do
|
28
|
+
|
29
|
+
deps do
|
30
|
+
require 'chef/encrypted_attribute'
|
31
|
+
require 'chef/json_compat'
|
32
|
+
end
|
33
|
+
|
34
|
+
option :encrypted_attribute_version,
|
35
|
+
:long => '--encrypted-attribute-version VERSION',
|
36
|
+
:description => 'Encrypted Attribute protocol version to use',
|
37
|
+
:proc => lambda { |i| Chef::Config[:knife][:encrypted_attributes][:version] = i }
|
38
|
+
|
39
|
+
option :encrypted_attribute_partial_search,
|
40
|
+
:short => '-P',
|
41
|
+
:long => '--disable-partial-search',
|
42
|
+
:description => 'Disable partial search',
|
43
|
+
:boolean => true,
|
44
|
+
:proc => lambda { |i| Chef::Config[:knife][:encrypted_attributes][:partial_search] = false }
|
45
|
+
|
46
|
+
option :encrypted_attribute_client_search,
|
47
|
+
:short => '-C CLIENT_SEARCH_QUERY',
|
48
|
+
:long => '--client-search CLIENT_SEARCH_QUERY',
|
49
|
+
:description => 'Client search query. Can be specified multiple times',
|
50
|
+
:proc => lambda { |i|
|
51
|
+
Chef::Config[:knife][:encrypted_attributes][:client_search] = [] unless Chef::Config[:knife][:encrypted_attributes][:client_search].kind_of?(Array)
|
52
|
+
Chef::Config[:knife][:encrypted_attributes][:client_search] << i
|
53
|
+
}
|
54
|
+
|
55
|
+
option :encrypted_attribute_users,
|
56
|
+
:short => '-U USER',
|
57
|
+
:long => '--encrypted-attribute-user USER',
|
58
|
+
:description => 'User name to allow access to. Can be specified multiple times',
|
59
|
+
:proc => lambda { |i|
|
60
|
+
Chef::Config[:knife][:encrypted_attributes][:users] = [] unless Chef::Config[:knife][:encrypted_attributes][:users].kind_of?(Array)
|
61
|
+
Chef::Config[:knife][:encrypted_attributes][:users] << i
|
62
|
+
}
|
63
|
+
|
64
|
+
# TODO option :keys
|
65
|
+
|
66
|
+
# Modified Chef::Knife::UI#edit_data method with plain text format support
|
67
|
+
def edit_data(data=nil, format='plain')
|
68
|
+
output = case format
|
69
|
+
when 'JSON', 'json'
|
70
|
+
data.nil? ? {} : Chef::JSONCompat.to_json_pretty(data, {:quirks_mode => true})
|
71
|
+
else
|
72
|
+
data.nil? ? '' : data
|
73
|
+
end
|
74
|
+
|
75
|
+
if !config[:disable_editing]
|
76
|
+
Tempfile.open([ 'knife-edit-', '.json' ]) do |tf|
|
77
|
+
tf.sync = true
|
78
|
+
tf.puts output
|
79
|
+
tf.close
|
80
|
+
raise 'Please set EDITOR environment variable' unless system("#{config[:editor]} #{tf.path}")
|
81
|
+
|
82
|
+
output = IO.read(tf.path)
|
83
|
+
tf.unlink # not needed, but recommended
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
case format
|
88
|
+
when 'JSON', 'json'
|
89
|
+
Yajl::Parser.parse(output)
|
90
|
+
else
|
91
|
+
output
|
92
|
+
end
|
93
|
+
end # def edit_data
|
94
|
+
|
95
|
+
end # includer.class_eval
|
96
|
+
end # self.included(includer)
|
97
|
+
end # EncryptedAttributeEditorOptions
|
98
|
+
end # Core
|
99
|
+
end # Knife
|
100
|
+
end # Chef
|