chef-vault 1.2.5 → 2.0.1.pre
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 +15 -0
- data/Changelog.md +17 -0
- data/KNIFE_EXAMPLES.md +169 -0
- data/README.md +83 -106
- data/bin/chef-vault +25 -19
- data/lib/chef-vault.rb +17 -9
- data/lib/chef-vault/certificate.rb +7 -28
- data/lib/chef-vault/chef_patch/api_client.rb +40 -0
- data/lib/chef-vault/chef_patch/user.rb +33 -0
- data/lib/chef-vault/exceptions.rb +27 -0
- data/lib/chef-vault/item.rb +243 -0
- data/lib/chef-vault/item_keys.rb +121 -0
- data/lib/chef-vault/user.rb +7 -28
- data/lib/chef-vault/version.rb +1 -1
- data/lib/chef/knife/Decrypt.rb +64 -0
- data/lib/chef/knife/encrypt_create.rb +91 -0
- data/lib/chef/knife/encrypt_delete.rb +62 -0
- data/lib/chef/knife/encrypt_remove.rb +100 -0
- data/lib/chef/knife/encrypt_rotate_keys.rb +62 -0
- data/lib/chef/knife/encrypt_update.rb +90 -0
- data/lib/{chef-vault/chef/offline.rb → chef/knife/mixin/compat.rb} +15 -11
- data/lib/chef/knife/mixin/helper.rb +50 -0
- data/spec/chef-vault_spec.rb +19 -30
- data/spec/item_keys_spec.rb +29 -0
- data/spec/item_spec.rb +33 -0
- metadata +23 -21
- data/lib/chef/knife/DecryptCert.rb +0 -59
- data/lib/chef/knife/DecryptPassword.rb +0 -58
- data/lib/chef/knife/EncryptCert.rb +0 -185
- data/lib/chef/knife/EncryptPassword.rb +0 -182
- data/lib/chef/knife/compat.rb +0 -71
data/lib/chef-vault/user.rb
CHANGED
@@ -15,38 +15,17 @@
|
|
15
15
|
|
16
16
|
class ChefVault
|
17
17
|
class User
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@username = username
|
22
|
-
@data_bag = data_bag
|
18
|
+
def initialize(vault, username)
|
19
|
+
@item = ChefVault::Item.load(vault, username)
|
20
|
+
end
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
chef.connect
|
27
|
-
end
|
22
|
+
def [](key)
|
23
|
+
@item[key]
|
28
24
|
end
|
29
25
|
|
30
26
|
def decrypt_password
|
31
|
-
|
32
|
-
|
33
|
-
private_key = OpenSSL::PKey::RSA.new(private_key)
|
34
|
-
|
35
|
-
begin
|
36
|
-
keys = Chef::DataBagItem.load(@data_bag, "#{username}_keys")
|
37
|
-
rescue
|
38
|
-
throw "Could not find data bag item #{username}_keys in data bag #{@data_bag}"
|
39
|
-
end
|
40
|
-
|
41
|
-
unless keys[Chef::Config[:node_name]]
|
42
|
-
throw "Password for #{username} is not encrypted for you! Rebuild the password data bag"
|
43
|
-
end
|
44
|
-
|
45
|
-
node_key = Base64.decode64(keys[Chef::Config[:node_name]])
|
46
|
-
shared_secret = private_key.private_decrypt(node_key)
|
47
|
-
cred = Chef::EncryptedDataBagItem.load(@data_bag, @username, shared_secret)
|
48
|
-
|
49
|
-
cred["password"]
|
27
|
+
puts "WARNING: This method is deprecated, please switch to item['value'] calls"
|
28
|
+
@item["password"]
|
50
29
|
end
|
51
30
|
end
|
52
31
|
end
|
data/lib/chef-vault/version.rb
CHANGED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Description: Chef-Vault Decrypt class
|
2
|
+
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'chef/knife'
|
17
|
+
require 'chef-vault'
|
18
|
+
|
19
|
+
class Decrypt < Chef::Knife
|
20
|
+
deps do
|
21
|
+
require 'chef/search/query'
|
22
|
+
require File.expand_path('../mixin/compat', __FILE__)
|
23
|
+
require File.expand_path('../mixin/helper', __FILE__)
|
24
|
+
include ChefVault::Mixin::KnifeCompat
|
25
|
+
include ChefVault::Mixin::Helper
|
26
|
+
end
|
27
|
+
|
28
|
+
banner "knife decrypt [VAULT] [ITEM] [VALUES] --mode MODE"
|
29
|
+
|
30
|
+
option :mode,
|
31
|
+
:short => '-M MODE',
|
32
|
+
:long => '--mode MODE',
|
33
|
+
:description => 'Chef mode to run in default - solo'
|
34
|
+
|
35
|
+
def run
|
36
|
+
vault = @name_args[0]
|
37
|
+
item = @name_args[1]
|
38
|
+
values = @name_args[2]
|
39
|
+
|
40
|
+
if vault && item && values
|
41
|
+
set_mode(config[:mode])
|
42
|
+
|
43
|
+
print_values(vault, item, values)
|
44
|
+
else
|
45
|
+
show_usage
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def show_usage
|
50
|
+
super
|
51
|
+
exit 1
|
52
|
+
end
|
53
|
+
|
54
|
+
def print_values(vault, item, values)
|
55
|
+
vault_item = ChefVault::Item.load(vault, item)
|
56
|
+
|
57
|
+
puts "#{vault}/#{item}"
|
58
|
+
|
59
|
+
values.split(",").each do |value|
|
60
|
+
value.strip! # remove white space
|
61
|
+
puts("\t#{value}: #{vault_item[value]}")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# Description: Chef-Vault EncryptCreate class
|
2
|
+
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'chef/knife'
|
17
|
+
require 'chef-vault'
|
18
|
+
|
19
|
+
class EncryptCreate < Chef::Knife
|
20
|
+
deps do
|
21
|
+
require 'chef/search/query'
|
22
|
+
require File.expand_path('../mixin/compat', __FILE__)
|
23
|
+
require File.expand_path('../mixin/helper', __FILE__)
|
24
|
+
include ChefVault::Mixin::KnifeCompat
|
25
|
+
include ChefVault::Mixin::Helper
|
26
|
+
end
|
27
|
+
|
28
|
+
banner "knife encrypt create [VAULT] [ITEM] [VALUES] "\
|
29
|
+
"--mode MODE --search SEARCH --admins ADMINS --json FILE"
|
30
|
+
|
31
|
+
option :mode,
|
32
|
+
:short => '-M MODE',
|
33
|
+
:long => '--mode MODE',
|
34
|
+
:description => 'Chef mode to run in default - solo'
|
35
|
+
|
36
|
+
option :search,
|
37
|
+
:short => '-S SEARCH',
|
38
|
+
:long => '--search SEARCH',
|
39
|
+
:description => 'Chef SOLR search for clients'
|
40
|
+
|
41
|
+
option :admins,
|
42
|
+
:short => '-A ADMINS',
|
43
|
+
:long => '--admins ADMINS',
|
44
|
+
:description => 'Chef users to be added as admins'
|
45
|
+
|
46
|
+
option :json,
|
47
|
+
:short => '-J FILE',
|
48
|
+
:long => '--json FILE',
|
49
|
+
:description => 'File containing JSON data to encrypt'
|
50
|
+
|
51
|
+
def run
|
52
|
+
vault = @name_args[0]
|
53
|
+
item = @name_args[1]
|
54
|
+
values = @name_args[2]
|
55
|
+
search = config[:search]
|
56
|
+
admins = config[:admins]
|
57
|
+
json_file = config[:json]
|
58
|
+
|
59
|
+
set_mode(config[:mode])
|
60
|
+
|
61
|
+
if vault && item && (values || json_file) && (search || admins)
|
62
|
+
begin
|
63
|
+
vault_item = ChefVault::Item.load(vault, item)
|
64
|
+
raise ChefVault::Exceptions::ItemAlreadyExists,
|
65
|
+
"#{vault_item.data_bag}/#{vault_item.id} already exists, "\
|
66
|
+
"use 'knife encrypt remove' and "\
|
67
|
+
"'knife encrypt update' to make changes."
|
68
|
+
rescue ChefVault::Exceptions::KeysNotFound,
|
69
|
+
ChefVault::Exceptions::ItemNotFound
|
70
|
+
vault_item = ChefVault::Item.new(vault, item)
|
71
|
+
|
72
|
+
merge_values(values, json_file).each do |key, value|
|
73
|
+
vault_item[key] = value
|
74
|
+
end
|
75
|
+
|
76
|
+
vault_item.clients(search) if search
|
77
|
+
vault_item.admins(admins) if admins
|
78
|
+
|
79
|
+
vault_item.save
|
80
|
+
end
|
81
|
+
else
|
82
|
+
show_usage
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def show_usage
|
87
|
+
super
|
88
|
+
exit 1
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Description: Chef-Vault EncryptDelete class
|
2
|
+
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'chef/knife'
|
17
|
+
require 'chef-vault'
|
18
|
+
|
19
|
+
class EncryptDelete < Chef::Knife
|
20
|
+
deps do
|
21
|
+
require 'chef/search/query'
|
22
|
+
require File.expand_path('../mixin/compat', __FILE__)
|
23
|
+
require File.expand_path('../mixin/helper', __FILE__)
|
24
|
+
include ChefVault::Mixin::KnifeCompat
|
25
|
+
include ChefVault::Mixin::Helper
|
26
|
+
end
|
27
|
+
|
28
|
+
banner "knife encrypt delete [VAULT] [ITEM] --mode MODE"
|
29
|
+
|
30
|
+
option :mode,
|
31
|
+
:short => '-M MODE',
|
32
|
+
:long => '--mode MODE',
|
33
|
+
:description => 'Chef mode to run in default - solo'
|
34
|
+
|
35
|
+
def run
|
36
|
+
vault = @name_args[0]
|
37
|
+
item = @name_args[1]
|
38
|
+
|
39
|
+
set_mode(config[:mode])
|
40
|
+
|
41
|
+
if vault && item
|
42
|
+
delete_object(ChefVault::Item, "#{vault}/#{item}", "chef_vault_item") do
|
43
|
+
begin
|
44
|
+
ChefVault::Item.load(vault, item).destroy
|
45
|
+
rescue ChefVault::Exceptions::KeysNotFound,
|
46
|
+
ChefVault::Exceptions::ItemNotFound
|
47
|
+
|
48
|
+
raise ChefVault::Exceptions::ItemNotFound,
|
49
|
+
"#{vault}/#{item} not found."
|
50
|
+
end
|
51
|
+
end
|
52
|
+
else
|
53
|
+
show_usage
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def show_usage
|
58
|
+
super
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# Description: Chef-Vault EncryptRemove class
|
2
|
+
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'chef/knife'
|
17
|
+
require 'chef-vault'
|
18
|
+
|
19
|
+
class EncryptRemove < Chef::Knife
|
20
|
+
deps do
|
21
|
+
require 'chef/search/query'
|
22
|
+
require File.expand_path('../mixin/compat', __FILE__)
|
23
|
+
require File.expand_path('../mixin/helper', __FILE__)
|
24
|
+
include ChefVault::Mixin::KnifeCompat
|
25
|
+
include ChefVault::Mixin::Helper
|
26
|
+
end
|
27
|
+
|
28
|
+
banner "knife encrypt remove [VAULT] [ITEM] [VALUES] "\
|
29
|
+
"--mode MODE --search SEARCH --admins ADMINS"
|
30
|
+
|
31
|
+
option :mode,
|
32
|
+
:short => '-M MODE',
|
33
|
+
:long => '--mode MODE',
|
34
|
+
:description => 'Chef mode to run in default - solo'
|
35
|
+
|
36
|
+
option :search,
|
37
|
+
:short => '-S SEARCH',
|
38
|
+
:long => '--search SEARCH',
|
39
|
+
:description => 'Chef SOLR search for clients'
|
40
|
+
|
41
|
+
option :admins,
|
42
|
+
:short => '-A ADMINS',
|
43
|
+
:long => '--admins ADMINS',
|
44
|
+
:description => 'Chef users to be added as admins'
|
45
|
+
|
46
|
+
def run
|
47
|
+
vault = @name_args[0]
|
48
|
+
item = @name_args[1]
|
49
|
+
values = @name_args[2]
|
50
|
+
search = config[:search]
|
51
|
+
admins = config[:admins]
|
52
|
+
json_file = config[:json]
|
53
|
+
|
54
|
+
set_mode(config[:mode])
|
55
|
+
|
56
|
+
if vault && item && ((values || json_file) || (search || admins))
|
57
|
+
begin
|
58
|
+
vault_item = ChefVault::Item.load(vault, item)
|
59
|
+
remove_items = []
|
60
|
+
|
61
|
+
if values || json_file
|
62
|
+
begin
|
63
|
+
json = JSON.parse(values)
|
64
|
+
json.each do |key, value|
|
65
|
+
remove_items << key
|
66
|
+
end
|
67
|
+
rescue JSON::ParserError
|
68
|
+
remove_items = values.split(",")
|
69
|
+
rescue Exception => e
|
70
|
+
raise e
|
71
|
+
end
|
72
|
+
|
73
|
+
remove_items.each do |key|
|
74
|
+
key.strip!
|
75
|
+
vault_item.remove(key)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
vault_item.clients(search, :delete) if search
|
80
|
+
vault_item.admins(admins, :delete) if admins
|
81
|
+
|
82
|
+
vault_item.save
|
83
|
+
rescue ChefVault::Exceptions::KeysNotFound,
|
84
|
+
ChefVault::Exceptions::ItemNotFound
|
85
|
+
|
86
|
+
raise ChefVault::Exceptions::ItemNotFound,
|
87
|
+
"#{vault}/#{item} does not exists, "\
|
88
|
+
"use 'knife encrypt create' to create."
|
89
|
+
end
|
90
|
+
else
|
91
|
+
show_usage
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def show_usage
|
96
|
+
super
|
97
|
+
exit 1
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Description: Chef-Vault EncryptRotateSecret class
|
2
|
+
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'chef/knife'
|
17
|
+
require 'chef-vault'
|
18
|
+
|
19
|
+
class EncryptRotateKeys < Chef::Knife
|
20
|
+
deps do
|
21
|
+
require 'chef/search/query'
|
22
|
+
require File.expand_path('../mixin/compat', __FILE__)
|
23
|
+
require File.expand_path('../mixin/helper', __FILE__)
|
24
|
+
include ChefVault::Mixin::KnifeCompat
|
25
|
+
include ChefVault::Mixin::Helper
|
26
|
+
end
|
27
|
+
|
28
|
+
banner "knife rotate secret [VAULT] [ITEM] --mode MODE"
|
29
|
+
|
30
|
+
option :mode,
|
31
|
+
:short => '-M MODE',
|
32
|
+
:long => '--mode MODE',
|
33
|
+
:description => 'Chef mode to run in default - solo'
|
34
|
+
|
35
|
+
def run
|
36
|
+
vault = @name_args[0]
|
37
|
+
item = @name_args[1]
|
38
|
+
|
39
|
+
if vault && item
|
40
|
+
set_mode(config[:mode])
|
41
|
+
|
42
|
+
begin
|
43
|
+
item = ChefVault::Item.load(vault, item)
|
44
|
+
item.rotate_keys!
|
45
|
+
rescue ChefVault::Exceptions::KeysNotFound,
|
46
|
+
ChefVault::Exceptions::ItemNotFound
|
47
|
+
|
48
|
+
raise ChefVault::Exceptions::ItemNotFound,
|
49
|
+
"#{vault}/#{item} does not exists, "\
|
50
|
+
"use 'knife encrypt create' to create."
|
51
|
+
end
|
52
|
+
else
|
53
|
+
show_usage
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def show_usage
|
58
|
+
super
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# Description: Chef-Vault EncryptUpdate class
|
2
|
+
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'chef/knife'
|
17
|
+
require 'chef-vault'
|
18
|
+
|
19
|
+
class EncryptUpdate < Chef::Knife
|
20
|
+
deps do
|
21
|
+
require 'chef/search/query'
|
22
|
+
require File.expand_path('../mixin/compat', __FILE__)
|
23
|
+
require File.expand_path('../mixin/helper', __FILE__)
|
24
|
+
include ChefVault::Mixin::KnifeCompat
|
25
|
+
include ChefVault::Mixin::Helper
|
26
|
+
end
|
27
|
+
|
28
|
+
banner "knife encrypt update [VAULT] [ITEM] [VALUES] "\
|
29
|
+
"--mode MODE --search SEARCH --admins ADMINS --json FILE"
|
30
|
+
|
31
|
+
option :mode,
|
32
|
+
:short => '-M MODE',
|
33
|
+
:long => '--mode MODE',
|
34
|
+
:description => 'Chef mode to run in default - solo'
|
35
|
+
|
36
|
+
option :search,
|
37
|
+
:short => '-S SEARCH',
|
38
|
+
:long => '--search SEARCH',
|
39
|
+
:description => 'Chef SOLR search for clients'
|
40
|
+
|
41
|
+
option :admins,
|
42
|
+
:short => '-A ADMINS',
|
43
|
+
:long => '--admins ADMINS',
|
44
|
+
:description => 'Chef users to be added as admins'
|
45
|
+
|
46
|
+
option :json,
|
47
|
+
:short => '-J FILE',
|
48
|
+
:long => '--json FILE',
|
49
|
+
:description => 'File containing JSON data to encrypt'
|
50
|
+
|
51
|
+
def run
|
52
|
+
vault = @name_args[0]
|
53
|
+
item = @name_args[1]
|
54
|
+
values = @name_args[2]
|
55
|
+
search = config[:search]
|
56
|
+
admins = config[:admins]
|
57
|
+
json_file = config[:json]
|
58
|
+
|
59
|
+
set_mode(config[:mode])
|
60
|
+
|
61
|
+
if vault && item && ((values || json_file) || (search || admins))
|
62
|
+
begin
|
63
|
+
vault_item = ChefVault::Item.load(vault, item)
|
64
|
+
|
65
|
+
merge_values(values, json_file).each do |key, value|
|
66
|
+
vault_item[key] = value
|
67
|
+
end
|
68
|
+
|
69
|
+
vault_item.clients(search) if search
|
70
|
+
vault_item.admins(admins) if admins
|
71
|
+
|
72
|
+
vault_item.save
|
73
|
+
rescue ChefVault::Exceptions::KeysNotFound,
|
74
|
+
ChefVault::Exceptions::ItemNotFound
|
75
|
+
|
76
|
+
raise ChefVault::Exceptions::ItemNotFound,
|
77
|
+
"#{vault}/#{item} does not exists, "\
|
78
|
+
"use 'knife encrypt create' to create."
|
79
|
+
end
|
80
|
+
else
|
81
|
+
show_usage
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def show_usage
|
86
|
+
super
|
87
|
+
exit 1
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|