knife-cloudformation 0.2.24 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +16 -0
- data/knife-cloudformation.gemspec +14 -4
- data/lib/knife-cloudformation.rb +0 -28
- data/lib/knife-cloudformation/version.rb +1 -1
- metadata +18 -80
- data/lib/chef/knife/cloudformation_create.rb +0 -147
- data/lib/chef/knife/cloudformation_describe.rb +0 -99
- data/lib/chef/knife/cloudformation_destroy.rb +0 -84
- data/lib/chef/knife/cloudformation_events.rb +0 -117
- data/lib/chef/knife/cloudformation_export.rb +0 -162
- data/lib/chef/knife/cloudformation_import.rb +0 -141
- data/lib/chef/knife/cloudformation_inspect.rb +0 -206
- data/lib/chef/knife/cloudformation_list.rb +0 -72
- data/lib/chef/knife/cloudformation_promote.rb +0 -40
- data/lib/chef/knife/cloudformation_update.rb +0 -137
- data/lib/chef/knife/cloudformation_validate.rb +0 -36
- data/lib/knife-cloudformation/cache.rb +0 -385
- data/lib/knife-cloudformation/knife.rb +0 -9
- data/lib/knife-cloudformation/knife/base.rb +0 -195
- data/lib/knife-cloudformation/knife/stack.rb +0 -197
- data/lib/knife-cloudformation/knife/template.rb +0 -213
- data/lib/knife-cloudformation/monkey_patch.rb +0 -8
- data/lib/knife-cloudformation/monkey_patch/stack.rb +0 -195
- data/lib/knife-cloudformation/provider.rb +0 -225
- data/lib/knife-cloudformation/utils.rb +0 -24
- data/lib/knife-cloudformation/utils/animal_strings.rb +0 -28
- data/lib/knife-cloudformation/utils/debug.rb +0 -31
- data/lib/knife-cloudformation/utils/json.rb +0 -64
- data/lib/knife-cloudformation/utils/object_storage.rb +0 -28
- data/lib/knife-cloudformation/utils/output.rb +0 -79
- data/lib/knife-cloudformation/utils/path_selector.rb +0 -99
- data/lib/knife-cloudformation/utils/ssher.rb +0 -29
- data/lib/knife-cloudformation/utils/stack_exporter.rb +0 -271
- data/lib/knife-cloudformation/utils/stack_parameter_scrubber.rb +0 -37
- data/lib/knife-cloudformation/utils/stack_parameter_validator.rb +0 -124
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'knife-cloudformation'
|
2
|
-
|
3
|
-
class Chef
|
4
|
-
class Knife
|
5
|
-
# Cloudformation destroy command
|
6
|
-
class CloudformationDestroy < Knife
|
7
|
-
|
8
|
-
include KnifeCloudformation::Knife::Base
|
9
|
-
|
10
|
-
banner 'knife cloudformation destroy NAME [NAME]'
|
11
|
-
|
12
|
-
option(:polling,
|
13
|
-
:long => '--[no-]poll',
|
14
|
-
:description => 'Enable stack event polling.',
|
15
|
-
:boolean => true,
|
16
|
-
:default => true,
|
17
|
-
:proc => lambda {|val| Chef::Config[:knife][:cloudformation][:poll] = val }
|
18
|
-
)
|
19
|
-
|
20
|
-
# Run the stack destruction action
|
21
|
-
def _run
|
22
|
-
stacks = name_args.sort
|
23
|
-
plural = 's' if stacks.size > 1
|
24
|
-
globs = stacks.find_all do |s|
|
25
|
-
s !~ /^[a-zA-Z0-9-]+$/
|
26
|
-
end
|
27
|
-
unless(globs.empty?)
|
28
|
-
glob_stacks = provider.connection.stacks.all.find_all do |remote_stack|
|
29
|
-
globs.detect do |glob|
|
30
|
-
File.fnmatch(glob, remote_stack.name)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
stacks += glob_stacks.map(&:name)
|
34
|
-
stacks -= globs
|
35
|
-
stacks.sort!
|
36
|
-
end
|
37
|
-
ui.warn "Destroying Cloud Formation#{plural}: #{ui.color(stacks.join(', '), :bold)}"
|
38
|
-
ui.confirm "Destroy formation#{plural}"
|
39
|
-
stacks.each do |stack_name|
|
40
|
-
stack = provider.connection.stacks.get(stack_name)
|
41
|
-
if(stack)
|
42
|
-
nested_stack_cleanup!(stack)
|
43
|
-
stack.destroy
|
44
|
-
else
|
45
|
-
ui.warn "Failed to locate requested stack: #{ui.color(stack_name, :bold)}"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
if(config[:polling])
|
49
|
-
if(stacks.size == 1)
|
50
|
-
poll_stack(stacks.first)
|
51
|
-
else
|
52
|
-
ui.error "Stack polling is not available when multiple stack deletion is requested!"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
ui.info " -> Destroyed Cloud Formation#{plural}: #{ui.color(stacks.join(', '), :bold, :red)}"
|
56
|
-
end
|
57
|
-
|
58
|
-
# Cleanup persisted templates if nested stack resources are included
|
59
|
-
def nested_stack_cleanup!(stack)
|
60
|
-
nest_stacks = stack.template.fetch('Resources', {}).values.find_all do |resource|
|
61
|
-
resource['Type'] == 'AWS::CloudFormation::Stack'
|
62
|
-
end.each do |resource|
|
63
|
-
url = resource['Properties']['TemplateURL']
|
64
|
-
if(url)
|
65
|
-
_, bucket_name, path = URI.parse(url).path.split('/', 3)
|
66
|
-
bucket = provider.connection.api_for(:storage).buckets.get(bucket_name)
|
67
|
-
if(bucket)
|
68
|
-
file = bucket.files.get(path)
|
69
|
-
if(file)
|
70
|
-
file.destroy
|
71
|
-
ui.info "Deleted nested stack template! (Bucket: #{bucket_name} Template: #{path})"
|
72
|
-
else
|
73
|
-
ui.warn "Failed to locate template file within bucket for deletion! (#{path})"
|
74
|
-
end
|
75
|
-
else
|
76
|
-
ui.warn "Failed to locate bucket containing template file for deletion! (#{bucket_name})"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
@@ -1,117 +0,0 @@
|
|
1
|
-
require 'knife-cloudformation'
|
2
|
-
|
3
|
-
class Chef
|
4
|
-
class Knife
|
5
|
-
# Cloudformation list command
|
6
|
-
class CloudformationEvents < Knife
|
7
|
-
|
8
|
-
banner 'knife cloudformation events NAME'
|
9
|
-
|
10
|
-
include KnifeCloudformation::Knife::Base
|
11
|
-
|
12
|
-
option(:polling,
|
13
|
-
:short => '-p',
|
14
|
-
:long => '--[no-]poll',
|
15
|
-
:boolean => true,
|
16
|
-
:default => true,
|
17
|
-
:description => 'Poll events while stack status is "in progress"',
|
18
|
-
:proc => lambda {|v| Chef::Config[:knife][:cloudformation][:poll] = v }
|
19
|
-
)
|
20
|
-
|
21
|
-
option(:attribute,
|
22
|
-
:short => '-a ATTR',
|
23
|
-
:long => '--attribute ATTR',
|
24
|
-
:description => 'Attribute to print. Can be used multiple times.',
|
25
|
-
:proc => lambda {|val|
|
26
|
-
Chef::Config[:knife][:cloudformation][:attributes] ||= []
|
27
|
-
Chef::Config[:knife][:cloudformation][:attributes].push(val).uniq!
|
28
|
-
}
|
29
|
-
)
|
30
|
-
|
31
|
-
option(:poll_delay,
|
32
|
-
:short => '-D secs',
|
33
|
-
:long => '--poll-delay secs',
|
34
|
-
:description => 'Number of seconds to pause between event poll',
|
35
|
-
:proc => lambda {|val|
|
36
|
-
Chef::Config[:knife][:cloudformation][:poll_delay] = val.to_i
|
37
|
-
}
|
38
|
-
)
|
39
|
-
|
40
|
-
option(:all_attributes,
|
41
|
-
:long => '--all-attributes',
|
42
|
-
:description => 'Print all attributes'
|
43
|
-
)
|
44
|
-
|
45
|
-
# Run the events list action
|
46
|
-
def _run
|
47
|
-
name = name_args.first
|
48
|
-
ui.info "Cloud Formation Events for Stack: #{ui.color(name, :bold)}\n"
|
49
|
-
stack = provider.connection.stacks.get(name)
|
50
|
-
last_id = nil
|
51
|
-
if(stack)
|
52
|
-
events = get_events(stack)
|
53
|
-
things_output(name, events, 'events')
|
54
|
-
last_id = events.last ? events.last[:id] : nil
|
55
|
-
if(Chef::Config[:knife][:cloudformation][:poll])
|
56
|
-
cycle_events = true
|
57
|
-
while(cycle_events)
|
58
|
-
cycle_events = stack.in_progress?
|
59
|
-
sleep(Chef::Config[:knife][:cloudformation][:poll_delay] || 10)
|
60
|
-
stack.events.reload
|
61
|
-
events = get_events(stack, last_id)
|
62
|
-
unless(events.empty?)
|
63
|
-
last_id = events.last[:id]
|
64
|
-
things_output(nil, events, 'events', :no_title, :ignore_empty_output)
|
65
|
-
end
|
66
|
-
nest_stacks = stack.resources.all.find_all do |resource|
|
67
|
-
resource.state.to_s.end_with?('in_progress') &&
|
68
|
-
resource.type == 'AWS::CloudFormation::Stack'
|
69
|
-
end
|
70
|
-
if(nest_stacks)
|
71
|
-
nest_stacks.each do |nest_stack|
|
72
|
-
begin
|
73
|
-
poll_stack(nest_stack.id)
|
74
|
-
ui.info "Complete event listing for nested stack (#{nest_stack.name})"
|
75
|
-
rescue => e
|
76
|
-
ui.warn "Error encountered on event listing for nested stack - #{e} (#{nest_stack.name})"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
stack.reload
|
81
|
-
end
|
82
|
-
# Extra to see completion
|
83
|
-
things_output(nil, get_events(stack, last_id), 'events', :no_title, :ignore_empty_output)
|
84
|
-
end
|
85
|
-
else
|
86
|
-
ui.fatal "Failed to locate requested stack: #{ui.color(name, :bold, :red)}"
|
87
|
-
raise "Failed to locate stack: #{name}!"
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# Fetch events from stack
|
92
|
-
#
|
93
|
-
# @param stack [Miasma::Models::Orchestration::Stack]
|
94
|
-
# @param last_id [String] only return events after this ID
|
95
|
-
# @return [Array<Hash>]
|
96
|
-
def get_events(stack, last_id=nil)
|
97
|
-
get_things do
|
98
|
-
stack_events = stack.events.all
|
99
|
-
if(last_id)
|
100
|
-
start_index = stack_events.index{|event| event.id == last_id}
|
101
|
-
events = stack_events.slice(0, start_index.to_i)
|
102
|
-
else
|
103
|
-
events = stack_events
|
104
|
-
end
|
105
|
-
events.map do |event|
|
106
|
-
Mash.new(event.attributes)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# @return [Array<String>] default attributes for events
|
112
|
-
def default_attributes
|
113
|
-
%w(time resource_logical_id resource_status resource_status_reason)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
@@ -1,162 +0,0 @@
|
|
1
|
-
require 'knife-cloudformation'
|
2
|
-
|
3
|
-
class Chef
|
4
|
-
class Knife
|
5
|
-
# Cloudformation export command
|
6
|
-
class CloudformationExport < Knife
|
7
|
-
|
8
|
-
include KnifeCloudformation::Knife::Base
|
9
|
-
include KnifeCloudformation::Utils::ObjectStorage
|
10
|
-
|
11
|
-
banner 'knife cloudformation export STACK_NAME'
|
12
|
-
|
13
|
-
option(:export_name,
|
14
|
-
:long => '--export-file-name NAME',
|
15
|
-
:description => 'File basename to contain the export. Can be callable block if defined within configuration',
|
16
|
-
:proc => lambda{|v| Chef::Config[:knife][:cloudformation][:export][:name] = v}
|
17
|
-
)
|
18
|
-
|
19
|
-
option(:path,
|
20
|
-
:long => '--export-path PATH',
|
21
|
-
:description => 'Directory path write export JSON file',
|
22
|
-
:proc => lambda{|v| Chef::Config[:knife][:cloudformation][:export][:path] = v}
|
23
|
-
)
|
24
|
-
|
25
|
-
option(:bucket,
|
26
|
-
:long => '--export-bucket BUCKET_NAME',
|
27
|
-
:description => 'Remote file bucket to write export JSON file',
|
28
|
-
:proc => lambda{|v| Chef::Config[:knife][:cloudformation][:export][:bucket] = v}
|
29
|
-
)
|
30
|
-
|
31
|
-
option(:bucket_prefix,
|
32
|
-
:long => '--bucket-key-prefix PREFIX',
|
33
|
-
:description => 'Key prefix for file storage in bucket. Can be callable block if defined within configuration',
|
34
|
-
:proc => lambda{|v| Chef::Config[:knife][:cloudformation][:export][:bucket_prefix] = v}
|
35
|
-
)
|
36
|
-
|
37
|
-
option(:ignore_parameters,
|
38
|
-
:short => '-P NAME',
|
39
|
-
:long => '--exclude-parameter NAME',
|
40
|
-
:description => 'Exclude parameter from export (can be used multiple times)',
|
41
|
-
:proc => lambda{|v|
|
42
|
-
Chef::Config[:knife][:cloudformation][:export][:ignore_parameters].push(v).uniq!
|
43
|
-
}
|
44
|
-
)
|
45
|
-
|
46
|
-
option(:chef_environment_parameter,
|
47
|
-
:long => '--chef-environment-parameter NAME',
|
48
|
-
:description => 'Parameter used within stack to specify Chef environment',
|
49
|
-
:proc => lambda{|v|
|
50
|
-
Chef::Config[:knife][:cloudformation][:export][:chef_environment_parameter] = v
|
51
|
-
}
|
52
|
-
)
|
53
|
-
|
54
|
-
option(:chef_popsicle,
|
55
|
-
:long => '--[no-]freeze-run-list',
|
56
|
-
:boolean => true,
|
57
|
-
:default => true,
|
58
|
-
:description => 'Freezes first run files',
|
59
|
-
:proc => lambda{|v| Chef::Config[:knife][:cloudformation][:export][:chef_popsicle] = v }
|
60
|
-
)
|
61
|
-
|
62
|
-
unless(Chef::Config[:knife][:cloudformation].has_key?(:export))
|
63
|
-
Chef::Config[:knife][:cloudformation][:export] = Mash.new(
|
64
|
-
:credentials => Mash.new,
|
65
|
-
:ignore_parameters => []
|
66
|
-
)
|
67
|
-
end
|
68
|
-
|
69
|
-
# Run export action
|
70
|
-
def _run
|
71
|
-
stack_name = name_args.first
|
72
|
-
ui.info "#{ui.color('Stack Export:', :bold)} #{stack_name}"
|
73
|
-
ui.confirm 'Perform export'
|
74
|
-
stack = provider.stacks.get(stack_name)
|
75
|
-
if(stack)
|
76
|
-
export_options = Mash.new.tap do |opts|
|
77
|
-
[:chef_popsicle, :chef_environment_parameter, :ignore_parameters].each do |key|
|
78
|
-
unless(Chef::Config[:knife][:cloudformation][:export][key].nil?)
|
79
|
-
opts[key] = Chef::Config[:knife][:cloudformation][:export][key]
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
exporter = KnifeCloudformation::Utils::StackExporter.new(stack, export_options)
|
84
|
-
result = exporter.export
|
85
|
-
outputs = [
|
86
|
-
write_to_file(result, stack),
|
87
|
-
write_to_bucket(result, stack)
|
88
|
-
].compact
|
89
|
-
if(outputs.empty?)
|
90
|
-
ui.warn 'No persistent output location defined. Printing export:'
|
91
|
-
ui.info _format_json(result)
|
92
|
-
end
|
93
|
-
ui.info "#{ui.color('Stack export', :bold)} (#{name_args.first}): #{ui.color('complete', :green)}"
|
94
|
-
unless(outputs.empty?)
|
95
|
-
outputs.each do |output|
|
96
|
-
ui.info ui.color(" -> #{output}", :blue)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
else
|
100
|
-
ui.fatal "Failed to discover requested stack: #{ui.color(stack_name, :red, :bold)}"
|
101
|
-
exit -1
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
# Generate file name for stack export JSON contents
|
106
|
-
#
|
107
|
-
# @param stack [Miasma::Models::Orchestration::Stack]
|
108
|
-
# @return [String] file name
|
109
|
-
def export_file_name(stack)
|
110
|
-
name = Chef::Config[:knife][:cloudformation][:export][:file]
|
111
|
-
if(name)
|
112
|
-
if(name.respond_to?(:call))
|
113
|
-
name.call(stack)
|
114
|
-
else
|
115
|
-
name.to_s
|
116
|
-
end
|
117
|
-
else
|
118
|
-
"#{stack.stack_name}-#{Time.now.to_i}.json"
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
# Write stack export to local file
|
123
|
-
#
|
124
|
-
# @param payload [Hash] stack export payload
|
125
|
-
# @param stack [Misama::Stack::Orchestration::Stack]
|
126
|
-
# @return [String, NilClass] path to file
|
127
|
-
def write_to_file(payload, stack)
|
128
|
-
raise NotImplementedError
|
129
|
-
if(Chef::Config[:knife][:cloudformation][:export][:path])
|
130
|
-
full_path = File.join(
|
131
|
-
File.expand_path(Chef::Config[:knife][:cloudformation][:export][:path]),
|
132
|
-
export_file_name(stack)
|
133
|
-
)
|
134
|
-
_, bucket, path = full_path.split('/', 3)
|
135
|
-
directory = provider.service_for(:storage,
|
136
|
-
:provider => :local,
|
137
|
-
:local_root => '/'
|
138
|
-
).directories.get(bucket)
|
139
|
-
file_store(payload, path, directory)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
# Write stack export to remote bucket
|
144
|
-
#
|
145
|
-
# @param payload [Hash] stack export payload
|
146
|
-
# @param stack [Miasma::Models::Orchestration::Stack]
|
147
|
-
# @return [String, NilClass] remote bucket key
|
148
|
-
def write_to_bucket(payload, stack)
|
149
|
-
raise NotImplementedError
|
150
|
-
if(bucket = Chef::Config[:knife][:cloudformation][:export][:bucket])
|
151
|
-
key_path = File.join(*[
|
152
|
-
bucket_prefix(stack),
|
153
|
-
export_file_name(stack)
|
154
|
-
].compact
|
155
|
-
)
|
156
|
-
file_store(payload, key_path, provider.service_for(:storage).directories.get(bucket))
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
@@ -1,141 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
require 'knife-cloudformation'
|
3
|
-
|
4
|
-
class Chef
|
5
|
-
class Knife
|
6
|
-
# Cloudformation import command
|
7
|
-
class CloudformationImport < Knife
|
8
|
-
|
9
|
-
include KnifeCloudformation::Knife::Base
|
10
|
-
include KnifeCloudformation::Utils::JSON
|
11
|
-
include KnifeCloudformation::Utils::ObjectStorage
|
12
|
-
include KnifeCloudformation::Utils::PathSelector
|
13
|
-
|
14
|
-
banner 'knife cloudformation import NEW_STACK_NAME [JSON_EXPORT_FILE]'
|
15
|
-
|
16
|
-
option(:path,
|
17
|
-
:long => '--import-path PATH',
|
18
|
-
:description => 'Directory path JSON export files are located',
|
19
|
-
:proc => lambda{|v|
|
20
|
-
Chef::Config[:knife][:cloudformation][:import][:path] = File.expand_path(v)
|
21
|
-
}
|
22
|
-
)
|
23
|
-
|
24
|
-
option(:bucket,
|
25
|
-
:long => '--export-bucket BUCKET_NAME',
|
26
|
-
:description => 'Remote file bucket JSON export files are located',
|
27
|
-
:proc => lambda{|v| Chef::Config[:knife][:cloudformation][:import][:bucket] = v}
|
28
|
-
)
|
29
|
-
|
30
|
-
option(:bucket_prefix,
|
31
|
-
:long => '--bucket-key-prefix PREFIX',
|
32
|
-
:description => 'Key prefix for file storage in bucket. Can be callable block if defined within configuration',
|
33
|
-
:proc => lambda{|v| Chef::Config[:knife][:cloudformation][:import][:bucket_prefix] = v}
|
34
|
-
)
|
35
|
-
|
36
|
-
unless(Chef::Config[:knife][:cloudformation].has_key?(:import))
|
37
|
-
Chef::Config[:knife][:cloudformation][:import] = Mash.new
|
38
|
-
end
|
39
|
-
|
40
|
-
# Run the import action
|
41
|
-
def _run
|
42
|
-
stack_name, json_file = name_args
|
43
|
-
ui.info "#{ui.color('Stack Import:', :bold)} #{stack_name}"
|
44
|
-
unless(json_file)
|
45
|
-
entries = [].tap do |_entries|
|
46
|
-
_entries.push('s3') if Chef::Config[:knife][:cloudformation][:import][:bucket]
|
47
|
-
_entries.push('fs') if Chef::Config[:knife][:cloudformation][:import][:path]
|
48
|
-
end
|
49
|
-
if(entries.size > 1)
|
50
|
-
valid = false
|
51
|
-
until(valid)
|
52
|
-
answer = ui.ask_question('Import via file system (fs) or remote bucket (remote)?', :default => 'remote')
|
53
|
-
valid = true if %w(remote fs).include?(answer)
|
54
|
-
entries = [answer]
|
55
|
-
end
|
56
|
-
elsif(entries.size < 1)
|
57
|
-
ui.fatal 'No path or bucket set. Unable to perform dynamic lookup!'
|
58
|
-
exit 1
|
59
|
-
end
|
60
|
-
case entries.first
|
61
|
-
when 'remote'
|
62
|
-
json_file = remote_discovery
|
63
|
-
else
|
64
|
-
json_file = local_discovery
|
65
|
-
end
|
66
|
-
end
|
67
|
-
if(File.exists?(json_file) || json_file.is_a?(IO))
|
68
|
-
content = json_file.is_a?(IO) ? json_file.read : File.read(json_file)
|
69
|
-
export = Mash.new(_from_json(content))
|
70
|
-
begin
|
71
|
-
creator = Chef::Knife::CloudformationCreate.new
|
72
|
-
creator.name_args = [stack_name]
|
73
|
-
Chef::Config[:knife][:cloudformation][:template] = _from_json(export[:stack][:template])
|
74
|
-
Chef::Config[:knife][:cloudformation][:options] = export[:stack][:options]
|
75
|
-
ui.info ' - Starting creation of import'
|
76
|
-
creator.run
|
77
|
-
ui.info "#{ui.color('Stack Import', :bold)} (#{json_file}): #{ui.color('complete', :green)}"
|
78
|
-
rescue => e
|
79
|
-
ui.fatal "Failed to import stack: #{e}"
|
80
|
-
debug "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
|
81
|
-
exit -1
|
82
|
-
end
|
83
|
-
else
|
84
|
-
ui.fatal "Failed to locate JSON export file (#{json_file})"
|
85
|
-
exit 1
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# Generate bucket prefix
|
90
|
-
#
|
91
|
-
# @return [String, NilClass]
|
92
|
-
def bucket_prefix
|
93
|
-
if(prefix = Chef::Config[:knife][:cloudformation][:import][:bucket_prefix])
|
94
|
-
if(prefix.respond_to?(:cal))
|
95
|
-
prefix.call
|
96
|
-
else
|
97
|
-
prefix.to_s
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
# Discover remote file
|
103
|
-
#
|
104
|
-
# @return [IO] stack export IO
|
105
|
-
def remote_discovery
|
106
|
-
storage = provider.service_for(:storage)
|
107
|
-
directory = storage.directories.get(
|
108
|
-
Chef::Config[:knife][:cloudformation][:import][:bucket]
|
109
|
-
)
|
110
|
-
file = prompt_for_file(
|
111
|
-
directory,
|
112
|
-
:directories_name => 'Collections',
|
113
|
-
:files_names => 'Exports',
|
114
|
-
:filter_prefix => bucket_prefix
|
115
|
-
)
|
116
|
-
if(file)
|
117
|
-
remote_file = storage.files.get(file)
|
118
|
-
StringIO.new(remote_file.body)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
# Discover remote file
|
123
|
-
#
|
124
|
-
# @return [IO] stack export IO
|
125
|
-
def local_discovery
|
126
|
-
_, bucket = Chef::Config[:knife][:cloudformation][:import][:path].split('/', 2)
|
127
|
-
storage = provider.service_for(:storage,
|
128
|
-
:provider => :local,
|
129
|
-
:local_root => '/'
|
130
|
-
)
|
131
|
-
directory = storage.directories.get(bucket)
|
132
|
-
prompt_for_file(
|
133
|
-
directory,
|
134
|
-
:directories_name => 'Collections',
|
135
|
-
:files_names => 'Exports'
|
136
|
-
)
|
137
|
-
end
|
138
|
-
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|