sfn 0.0.1 → 0.3.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/CHANGELOG.md +107 -0
- data/LICENSE +13 -0
- data/README.md +142 -61
- data/bin/sfn +43 -0
- data/lib/chef/knife/knife_plugin_seed.rb +117 -0
- data/lib/sfn.rb +17 -0
- data/lib/sfn/cache.rb +385 -0
- data/lib/sfn/command.rb +45 -0
- data/lib/sfn/command/create.rb +87 -0
- data/lib/sfn/command/describe.rb +87 -0
- data/lib/sfn/command/destroy.rb +74 -0
- data/lib/sfn/command/events.rb +98 -0
- data/lib/sfn/command/export.rb +103 -0
- data/lib/sfn/command/import.rb +117 -0
- data/lib/sfn/command/inspect.rb +160 -0
- data/lib/sfn/command/list.rb +59 -0
- data/lib/sfn/command/promote.rb +17 -0
- data/lib/sfn/command/update.rb +95 -0
- data/lib/sfn/command/validate.rb +34 -0
- data/lib/sfn/command_module.rb +9 -0
- data/lib/sfn/command_module/base.rb +150 -0
- data/lib/sfn/command_module/stack.rb +166 -0
- data/lib/sfn/command_module/template.rb +147 -0
- data/lib/sfn/config.rb +106 -0
- data/lib/sfn/config/create.rb +35 -0
- data/lib/sfn/config/describe.rb +19 -0
- data/lib/sfn/config/destroy.rb +9 -0
- data/lib/sfn/config/events.rb +25 -0
- data/lib/sfn/config/export.rb +29 -0
- data/lib/sfn/config/import.rb +24 -0
- data/lib/sfn/config/inspect.rb +37 -0
- data/lib/sfn/config/list.rb +25 -0
- data/lib/sfn/config/promote.rb +23 -0
- data/lib/sfn/config/update.rb +20 -0
- data/lib/sfn/config/validate.rb +49 -0
- data/lib/sfn/monkey_patch.rb +8 -0
- data/lib/sfn/monkey_patch/stack.rb +200 -0
- data/lib/sfn/provider.rb +224 -0
- data/lib/sfn/utils.rb +23 -0
- data/lib/sfn/utils/debug.rb +31 -0
- data/lib/sfn/utils/json.rb +37 -0
- data/lib/sfn/utils/object_storage.rb +28 -0
- data/lib/sfn/utils/output.rb +79 -0
- data/lib/sfn/utils/path_selector.rb +99 -0
- data/lib/sfn/utils/ssher.rb +29 -0
- data/lib/sfn/utils/stack_exporter.rb +275 -0
- data/lib/sfn/utils/stack_parameter_scrubber.rb +37 -0
- data/lib/sfn/utils/stack_parameter_validator.rb +124 -0
- data/lib/sfn/version.rb +4 -0
- data/sfn.gemspec +19 -0
- metadata +110 -4
data/lib/sfn/config.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
require 'bogo-config'
|
3
|
+
|
4
|
+
module Sfn
|
5
|
+
|
6
|
+
# Top level configuration
|
7
|
+
class Config < Bogo::Config
|
8
|
+
|
9
|
+
# Only values allowed designating bool type
|
10
|
+
BOOLEAN_VALUES = [TrueClass, FalseClass]
|
11
|
+
|
12
|
+
autoload :Create, 'sfn/config/create'
|
13
|
+
autoload :Describe, 'sfn/config/describe'
|
14
|
+
autoload :Destroy, 'sfn/config/destroy'
|
15
|
+
autoload :Describe, 'sfn/config/describe'
|
16
|
+
autoload :Events, 'sfn/config/events'
|
17
|
+
autoload :Export, 'sfn/config/export'
|
18
|
+
autoload :Import, 'sfn/config/import'
|
19
|
+
autoload :Inspect, 'sfn/config/inspect'
|
20
|
+
autoload :List, 'sfn/config/list'
|
21
|
+
autoload :Promote, 'sfn/config/promote'
|
22
|
+
autoload :Update, 'sfn/config/update'
|
23
|
+
autoload :Validate, 'sfn/config/validate'
|
24
|
+
|
25
|
+
attribute(
|
26
|
+
:credentials, Smash,
|
27
|
+
:coerce => proc{|v|
|
28
|
+
v = Smash[v.split(',').map{|x| v.split('=')}] if v.is_a?(String)
|
29
|
+
v.to_smash
|
30
|
+
},
|
31
|
+
:description => 'Provider credentials'
|
32
|
+
)
|
33
|
+
attribute(
|
34
|
+
:ignore_parameters, String,
|
35
|
+
:multiple => true,
|
36
|
+
:description => 'Parameters to ignore during modifications'
|
37
|
+
)
|
38
|
+
attribute(
|
39
|
+
:interactive_parameters, [TrueClass, FalseClass],
|
40
|
+
:default => true,
|
41
|
+
:description => 'Prompt for template parameters'
|
42
|
+
)
|
43
|
+
attribute(
|
44
|
+
:poll, [TrueClass, FalseClass],
|
45
|
+
:default => true,
|
46
|
+
:description => 'Poll stack events on modification actions'
|
47
|
+
)
|
48
|
+
attribute(
|
49
|
+
:defaults, [TrueClass, FalseClass],
|
50
|
+
:description => 'Automatically accept default values'
|
51
|
+
)
|
52
|
+
attribute(
|
53
|
+
:yes, [TrueClass, FalseClass],
|
54
|
+
:description => 'Automatically accept any requests for confirmation'
|
55
|
+
)
|
56
|
+
attribute(
|
57
|
+
:config, String,
|
58
|
+
:description => 'Configuration file path'
|
59
|
+
)
|
60
|
+
|
61
|
+
attribute :create, Create, :coerce => proc{|v| Create.new(v)}
|
62
|
+
attribute :update, Update, :coerce => proc{|v| Update.new(v)}
|
63
|
+
attribute :destroy, Destroy, :coerce => proc{|v| Destroy.new(v)}
|
64
|
+
attribute :events, Events, :coerce => proc{|v| Events.new(v)}
|
65
|
+
attribute :export, Export, :coerce => proc{|v| Export.new(v)}
|
66
|
+
attribute :import, Import, :coerce => proc{|v| Import.new(v)}
|
67
|
+
attribute :inspect, Inspect, :coerce => proc{|v| Inpsect.new(v)}
|
68
|
+
attribute :describe, Describe, :coerce => proc{|v| Describe.new(v)}
|
69
|
+
attribute :list, List, :coerce => proc{|v| List.new(v)}
|
70
|
+
attribute :promote, Promote, :coerce => proc{|v| Promote.new(v)}
|
71
|
+
attribute :validate, Validate, :coerce => proc{|v| Validate.new(v)}
|
72
|
+
|
73
|
+
# Provide all options for config class (includes global configs)
|
74
|
+
#
|
75
|
+
# @param klass [Class]
|
76
|
+
# @return [Smash]
|
77
|
+
def self.options_for(klass)
|
78
|
+
shorts = ['h'] # always reserve `-h` for help
|
79
|
+
_options_for(self, shorts).merge(
|
80
|
+
_options_for(klass, shorts)
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Provide options for config class
|
85
|
+
#
|
86
|
+
# @param klass [Class]
|
87
|
+
# @param shorts [Array<String>]
|
88
|
+
# @return [Smash]
|
89
|
+
def self._options_for(klass, shorts)
|
90
|
+
Smash[
|
91
|
+
klass.attributes.sort_by(&:first).map do |name, info|
|
92
|
+
next unless info[:description]
|
93
|
+
short = name.chars.zip(name.chars.map(&:upcase)).flatten.detect do |c|
|
94
|
+
!shorts.include?(c)
|
95
|
+
end
|
96
|
+
shorts << short
|
97
|
+
info[:short] = short
|
98
|
+
info[:long] = name.tr('_', '-')
|
99
|
+
info[:boolean] = [info[:type]].compact.flatten.all?{|t| BOOLEAN_VALUES.include?(t)}
|
100
|
+
[name, info]
|
101
|
+
end.compact
|
102
|
+
]
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Config
|
5
|
+
# Create command configuration
|
6
|
+
class Create < Update
|
7
|
+
|
8
|
+
attribute(
|
9
|
+
:timeout, Integer,
|
10
|
+
:coerce => proc{|v| v.to_i},
|
11
|
+
:description => 'Seconds to wait for stack to complete'
|
12
|
+
)
|
13
|
+
attribute(
|
14
|
+
:rollback, [TrueClass, FalseClass],
|
15
|
+
:description => 'Rollback stack on failure'
|
16
|
+
)
|
17
|
+
attribute(
|
18
|
+
:capabilities, String,
|
19
|
+
:multiple => true,
|
20
|
+
:description => 'Capabilities to allow the stack'
|
21
|
+
)
|
22
|
+
attribute(
|
23
|
+
:options, String,
|
24
|
+
:multiple => true,
|
25
|
+
:description => 'Extra options to apply to the API call'
|
26
|
+
)
|
27
|
+
attribute(
|
28
|
+
:notifications, String,
|
29
|
+
:multiple => true,
|
30
|
+
:description => 'Notification endpoints for stack events'
|
31
|
+
)
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Config
|
5
|
+
class Describe < Bogo::Config
|
6
|
+
|
7
|
+
attribute(
|
8
|
+
:resources, [TrueClass, FalseClass],
|
9
|
+
:description => 'Display stack resource list'
|
10
|
+
)
|
11
|
+
|
12
|
+
attribute(
|
13
|
+
:outputs, [TrueClass, FalseClass],
|
14
|
+
:description => 'Display stack outputs'
|
15
|
+
)
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Config
|
5
|
+
# Events command configuration
|
6
|
+
class Events < Bogo::Config
|
7
|
+
|
8
|
+
attribute(
|
9
|
+
:attribute, String,
|
10
|
+
:multiple => true,
|
11
|
+
:description => 'Event attribute to display'
|
12
|
+
)
|
13
|
+
attribute(
|
14
|
+
:poll_delay, Integer,
|
15
|
+
:default => 20,
|
16
|
+
:description => 'Seconds to pause between each event poll'
|
17
|
+
)
|
18
|
+
attribute(
|
19
|
+
:all_attributes, [TrueClass, FalseClass],
|
20
|
+
:description => 'Display all event attributes'
|
21
|
+
)
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Config
|
5
|
+
|
6
|
+
# Export command configuration
|
7
|
+
class Export < Bogo::Config
|
8
|
+
|
9
|
+
attribute(
|
10
|
+
:name, String,
|
11
|
+
:description => 'Export file base name'
|
12
|
+
)
|
13
|
+
attribute(
|
14
|
+
:path, String,
|
15
|
+
:description => 'Local path prefix for dump file'
|
16
|
+
)
|
17
|
+
attribute(
|
18
|
+
:bucket, String,
|
19
|
+
:description => 'Remote storage bucket'
|
20
|
+
)
|
21
|
+
attribute(
|
22
|
+
:bucket_prefix, String,
|
23
|
+
:description => 'Remote key prefix within bucket for dump file'
|
24
|
+
)
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Config
|
5
|
+
|
6
|
+
# Import command configuration
|
7
|
+
class Import < Bogo::Config
|
8
|
+
|
9
|
+
attribute(
|
10
|
+
:path, String,
|
11
|
+
:description => 'Directory path JSON export files are located'
|
12
|
+
)
|
13
|
+
attribute(
|
14
|
+
:bucket, String,
|
15
|
+
:description => 'Remote storage bucket JSON export files are located'
|
16
|
+
)
|
17
|
+
attribute(
|
18
|
+
:bucket_prefix, String,
|
19
|
+
:description => 'Remote key prefix within bucket for dump file'
|
20
|
+
)
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Config
|
5
|
+
# Inspect command configuration
|
6
|
+
class Inspect < Bogo::Config
|
7
|
+
|
8
|
+
attribute(
|
9
|
+
:attribute, String,
|
10
|
+
:multiple => true,
|
11
|
+
:description => 'Dot delimited attribute to view'
|
12
|
+
)
|
13
|
+
attribute(
|
14
|
+
:nodes, [TrueClass, FalseClass],
|
15
|
+
:description => 'Locate all instances and display addresses'
|
16
|
+
)
|
17
|
+
attribute(
|
18
|
+
:instance_failure, String,
|
19
|
+
:description => 'Display log file error from failed not if possible',
|
20
|
+
)
|
21
|
+
attribute(
|
22
|
+
:failure_log_path, String,
|
23
|
+
:description => 'Path to remote log file for display on failure',
|
24
|
+
:default => '/var/log/chef/client.log'
|
25
|
+
)
|
26
|
+
attribute(
|
27
|
+
:identity_file, String,
|
28
|
+
:description => 'SSH identity file for authentication'
|
29
|
+
)
|
30
|
+
attribute(
|
31
|
+
:ssh_user, String,
|
32
|
+
:description => 'SSH username for inspection connect'
|
33
|
+
)
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Config
|
5
|
+
# List command configuration
|
6
|
+
class List < Bogo::Config
|
7
|
+
|
8
|
+
attribute(
|
9
|
+
:attribute, String,
|
10
|
+
:multiple => true,
|
11
|
+
:description => 'Attribute of stack to print'
|
12
|
+
)
|
13
|
+
attribute(
|
14
|
+
:all_attributes, [TrueClass, FalseClass],
|
15
|
+
:description => 'Print all available attributes'
|
16
|
+
)
|
17
|
+
attribute(
|
18
|
+
:status, String,
|
19
|
+
:multiple => true,
|
20
|
+
:description => 'Match stacks with given status. Use "none" to disable.'
|
21
|
+
)
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Config
|
5
|
+
# Promote command configuration
|
6
|
+
class Promote < Bogo::Config
|
7
|
+
|
8
|
+
attribute(
|
9
|
+
:accounts, String,
|
10
|
+
:description => 'JSON accounts file path'
|
11
|
+
)
|
12
|
+
attribute(
|
13
|
+
:bucket, String,
|
14
|
+
:description => 'Bucket name containing the exports'
|
15
|
+
)
|
16
|
+
attribute(
|
17
|
+
:bucket_prefix, String,
|
18
|
+
:description => 'Key prefix within remote bucket'
|
19
|
+
)
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Config
|
5
|
+
# Update command configuration
|
6
|
+
class Update < Validate
|
7
|
+
|
8
|
+
attribute(
|
9
|
+
:print_only, [TrueClass, FalseClass],
|
10
|
+
:description => 'Print the resulting stack template'
|
11
|
+
)
|
12
|
+
attribute(
|
13
|
+
:apply_stack, String,
|
14
|
+
:multiple => true,
|
15
|
+
:description => 'Apply outputs from stack to input parameters'
|
16
|
+
)
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
class Config
|
5
|
+
# Validate command configuration
|
6
|
+
class Validate < Bogo::Config
|
7
|
+
|
8
|
+
attribute(
|
9
|
+
:processing, [TrueClass, FalseClass],
|
10
|
+
:description => 'Call the unicorns and explode the glitter bombs'
|
11
|
+
)
|
12
|
+
attribute(
|
13
|
+
:file, String,
|
14
|
+
:description => 'Path to template file'
|
15
|
+
)
|
16
|
+
attribute(
|
17
|
+
:file_path_prompt, [TrueClass, FalseClass],
|
18
|
+
:default => true,
|
19
|
+
:description => 'Enable interactive prompt for template path discovery'
|
20
|
+
)
|
21
|
+
attribute(
|
22
|
+
:base_directory, String,
|
23
|
+
:description => 'Path to root of of templates directory'
|
24
|
+
)
|
25
|
+
attribute(
|
26
|
+
:no_base_directory, [TrueClass, FalseClass],
|
27
|
+
:description => 'Unset any value used for the template root directory path'
|
28
|
+
)
|
29
|
+
attribute(
|
30
|
+
:translate, String,
|
31
|
+
:description => 'Translate generated template to given prodiver'
|
32
|
+
)
|
33
|
+
attribute(
|
34
|
+
:translate_chunk, Integer,
|
35
|
+
:description => 'Chunk length for serialization'
|
36
|
+
)
|
37
|
+
attribute(
|
38
|
+
:apply_nesting, [TrueClass, FalseClass],
|
39
|
+
:default => true,
|
40
|
+
:description => 'Apply stack nesting'
|
41
|
+
)
|
42
|
+
attribute(
|
43
|
+
:nesting_bucket, String,
|
44
|
+
:description => 'Bucket to use for storing nested stack templates'
|
45
|
+
)
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'sfn'
|
3
|
+
|
4
|
+
module Sfn
|
5
|
+
module MonkeyPatch
|
6
|
+
|
7
|
+
# Expand stack model functionality
|
8
|
+
module Stack
|
9
|
+
|
10
|
+
include Bogo::AnimalStrings
|
11
|
+
|
12
|
+
## Status helpers
|
13
|
+
|
14
|
+
# Check for state suffix
|
15
|
+
#
|
16
|
+
# @param args [String, Symbol] state suffix to check for (multiple allowed)
|
17
|
+
# @return [TrueClass, FalseClass] true if any matches found in argument list
|
18
|
+
def status_ends_with?(*args)
|
19
|
+
stat = status.to_s.downcase
|
20
|
+
!!args.map(&:to_s).map(&:downcase).detect do |suffix|
|
21
|
+
stat.end_with?(suffix)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check for state prefix
|
26
|
+
#
|
27
|
+
# @param args [String, Symbol] state prefix to check for (multiple allowed)
|
28
|
+
# @return [TrueClass, FalseClass] true if any matches found in argument list
|
29
|
+
def status_starts_with?(*args)
|
30
|
+
stat = status.to_s.downcase
|
31
|
+
!!args.map(&:to_s).map(&:downcase).detect do |prefix|
|
32
|
+
stat.start_with?(prefix)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Check for state inclusion
|
37
|
+
#
|
38
|
+
# @param args [String, Symbol] state string to check for (multiple allowed)
|
39
|
+
# @return [TrueClass, FalseClass] true if any matches found in argument list
|
40
|
+
def status_includes?(*args)
|
41
|
+
stat = status.to_s.downcase
|
42
|
+
!!args.map(&:to_s).map(&:downcase).detect do |string|
|
43
|
+
stat.include?(string)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [TrueClass, FalseClass] stack is in progress
|
48
|
+
def in_progress?
|
49
|
+
status_ends_with?(:in_progress)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [TrueClass, FalseClass] stack is in complete state
|
53
|
+
def complete?
|
54
|
+
status_ends_with?(:complete, :failed)
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [TrueClass, FalseClass] stack is failed state
|
58
|
+
def failed?
|
59
|
+
status_ends_with?(:failed) ||
|
60
|
+
(status_includes?(:rollback) && status_ends_with?(:complete))
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [TrueClass, FalseClass] stack is in success state
|
64
|
+
def success?
|
65
|
+
!failed? && complete?
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [TrueClass, FalseClass] stack is creating
|
69
|
+
def creating?
|
70
|
+
in_progress? && status_starts_with?(:create)
|
71
|
+
end
|
72
|
+
|
73
|
+
# @return [TrueClass, FalseClass] stack is deleting
|
74
|
+
def deleting?
|
75
|
+
in_progress? && status_starts_with?(:delete)
|
76
|
+
end
|
77
|
+
|
78
|
+
# @return [TrueClass, FalseClass] stack is updating
|
79
|
+
def updating?
|
80
|
+
in_progress? && status_starts_with?(:update)
|
81
|
+
end
|
82
|
+
|
83
|
+
# @return [TrueClass, FalseClass] stack is rolling back
|
84
|
+
def rollbacking?
|
85
|
+
in_progress? && status_starts_with?(:rollback)
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [String] action currently being performed
|
89
|
+
def performing
|
90
|
+
if(in_progress?)
|
91
|
+
status.to_s.downcase.split('_').first.to_sym
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
### Color coders
|
96
|
+
|
97
|
+
# @return [TrueClass, FalseClass] stack is in red state
|
98
|
+
def red?
|
99
|
+
failed? || deleting?
|
100
|
+
end
|
101
|
+
|
102
|
+
# @return [TrueClass, FalseClass] stack is in green state
|
103
|
+
def green?
|
104
|
+
success?
|
105
|
+
end
|
106
|
+
|
107
|
+
# @return [TrueClass, FalseClass] stack is in yellow state
|
108
|
+
def yellow?
|
109
|
+
!red? && !green?
|
110
|
+
end
|
111
|
+
|
112
|
+
# Provides color of stack state. Red is an error state, yellow
|
113
|
+
# is a warning state and green is a success state
|
114
|
+
#
|
115
|
+
# @return [Symbol] color of state (:red, :yellow, :green)
|
116
|
+
def color_state
|
117
|
+
red? ? :red : green? ? :green : :yellow
|
118
|
+
end
|
119
|
+
|
120
|
+
# Provides text of stack state. Danger is an error state, warning
|
121
|
+
# is a warning state and success is a success state
|
122
|
+
#
|
123
|
+
# @return [Symbol] color of state (:danger, :warning, :success)
|
124
|
+
def text_state
|
125
|
+
red? ? :danger : green? ? :success : :warning
|
126
|
+
end
|
127
|
+
|
128
|
+
# @return [String] URL safe encoded stack id
|
129
|
+
def encoded_id
|
130
|
+
Base64.urlsafe_encode64(id)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Whole number representation of current completion
|
134
|
+
#
|
135
|
+
# @param min [Integer] lowest allowed return value (defaults 5)
|
136
|
+
# @return [Integer] percent complete (0..100)
|
137
|
+
def percent_complete(min = 5)
|
138
|
+
if(in_progress?)
|
139
|
+
total_resources = load_template.fetch('Resources', []).size
|
140
|
+
total_complete = resources.all.find_all do |resource|
|
141
|
+
resource.resource_status.downcase.end_with?('complete')
|
142
|
+
end.size
|
143
|
+
result = ((total_complete.to_f / total_resources) * 100).to_i
|
144
|
+
result > min.to_i ? result : min
|
145
|
+
else
|
146
|
+
100
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# Apply stack outputs to current stack parameters
|
151
|
+
#
|
152
|
+
# @param remote_stack [Miasma::Orchestration::Stack]
|
153
|
+
# @return [self]
|
154
|
+
# @note setting `DisableApply` within parameter hash will
|
155
|
+
# prevent parameters being overridden
|
156
|
+
def apply_stack(remote_stack, ignore_params=nil)
|
157
|
+
default_key = 'Default'
|
158
|
+
stack_parameters = template['Parameters']
|
159
|
+
valid_parameters = Smash[
|
160
|
+
stack_parameters.map do |key, val|
|
161
|
+
unless(val['DisableApply'])
|
162
|
+
[snake(key), key]
|
163
|
+
end
|
164
|
+
end.compact
|
165
|
+
]
|
166
|
+
unless(ignore_params)
|
167
|
+
if(defined?(Chef::Config))
|
168
|
+
ignore_params = Chef::Config[:knife].to_smash.get(:cloudformation, :ignore_parameters)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
if(ignore_params)
|
172
|
+
valid_parameters = Hash[
|
173
|
+
valid_parameters.map do |snake_param, camel_param|
|
174
|
+
unless(ignore_params.include?(camel_param))
|
175
|
+
[snake_param, camel_param]
|
176
|
+
end
|
177
|
+
end.compact
|
178
|
+
]
|
179
|
+
end
|
180
|
+
if(persisted?)
|
181
|
+
remote_stack.outputs.each do |output|
|
182
|
+
if(param_key = valid_parameters[snake(output.key)])
|
183
|
+
parameters.merge!(param_key => output.value)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
else
|
187
|
+
remote_stack.outputs.each do |output|
|
188
|
+
if(param_key = valid_parameters[snake(output.key)])
|
189
|
+
stack_parameters[param_key][default_key] = output.value
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Infect miasma
|
200
|
+
Miasma::Models::Orchestration::Stack.send(:include, Sfn::MonkeyPatch::Stack)
|