stax 0.0.3 → 0.0.4
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 +5 -5
- data/README.md +205 -13
- data/lib/stax.rb +6 -1
- data/lib/stax/aws/asg.rb +1 -0
- data/lib/stax/aws/cfn.rb +64 -3
- data/lib/stax/aws/codebuild.rb +41 -0
- data/lib/stax/aws/codepipeline.rb +44 -0
- data/lib/stax/aws/dynamodb.rb +10 -0
- data/lib/stax/aws/ec2.rb +11 -0
- data/lib/stax/aws/ecr.rb +17 -0
- data/lib/stax/aws/ecs.rb +5 -5
- data/lib/stax/aws/route53.rb +51 -0
- data/lib/stax/base.rb +18 -0
- data/lib/stax/cfer.rb +43 -33
- data/lib/stax/cli.rb +3 -5
- data/lib/stax/meta.rb +18 -0
- data/lib/stax/mixin/asg.rb +1 -1
- data/lib/stax/mixin/codebuild.rb +98 -0
- data/lib/stax/mixin/codepipeline.rb +125 -0
- data/lib/stax/mixin/dynamodb.rb +17 -1
- data/lib/stax/mixin/ec2.rb +6 -1
- data/lib/stax/mixin/ecr.rb +68 -0
- data/lib/stax/mixin/ecs.rb +98 -33
- data/lib/stax/mixin/ecs/deploy.rb +49 -0
- data/lib/stax/mixin/logs.rb +73 -2
- data/lib/stax/stack.rb +8 -6
- data/lib/stax/stack/cfn.rb +49 -8
- data/lib/stax/stack/changeset.rb +88 -0
- data/lib/stax/stack/crud.rb +143 -26
- data/lib/stax/stack/imports.rb +34 -0
- data/lib/stax/stack/outputs.rb +4 -2
- data/lib/stax/stack/parameters.rb +1 -1
- data/lib/stax/stack/resources.rb +3 -3
- data/lib/stax/staxfile.rb +14 -4
- data/lib/stax/version.rb +1 -1
- metadata +12 -4
- data/lib/stax/asg.rb +0 -140
data/lib/stax/stack/outputs.rb
CHANGED
@@ -3,7 +3,7 @@ module Stax
|
|
3
3
|
|
4
4
|
no_commands do
|
5
5
|
def stack_outputs
|
6
|
-
@_stack_outputs ||= Cfn.outputs(stack_name)
|
6
|
+
@_stack_outputs ||= Aws::Cfn.outputs(stack_name)
|
7
7
|
end
|
8
8
|
|
9
9
|
def stack_output(key)
|
@@ -16,7 +16,9 @@ module Stax
|
|
16
16
|
if key
|
17
17
|
puts stack_output(key)
|
18
18
|
else
|
19
|
-
print_table
|
19
|
+
print_table Aws::Cfn.describe(stack_name).outputs.map { |o|
|
20
|
+
[o.output_key, o.output_value, o.description, o.export_name]
|
21
|
+
}.sort
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
data/lib/stax/stack/resources.rb
CHANGED
@@ -3,7 +3,7 @@ module Stax
|
|
3
3
|
|
4
4
|
no_commands do
|
5
5
|
def stack_resources
|
6
|
-
@_stack_resources ||= Cfn.resources(stack_name)
|
6
|
+
@_stack_resources ||= Aws::Cfn.resources(stack_name)
|
7
7
|
end
|
8
8
|
|
9
9
|
def stack_resources_by_type(type)
|
@@ -22,13 +22,13 @@ module Stax
|
|
22
22
|
resources.select! { |r| m.match(r.resource_type) }
|
23
23
|
end
|
24
24
|
}.map { |r|
|
25
|
-
[r.logical_resource_id, r.resource_type, color(r.resource_status, Cfn::COLORS), r.physical_resource_id]
|
25
|
+
[r.logical_resource_id, r.resource_type, color(r.resource_status, Aws::Cfn::COLORS), r.physical_resource_id]
|
26
26
|
}
|
27
27
|
end
|
28
28
|
|
29
29
|
desc 'id [LOGICAL_ID]', 'get physical ID from resource logical ID'
|
30
30
|
def id(resource)
|
31
|
-
puts Cfn.id(stack_name, resource)
|
31
|
+
puts Aws::Cfn.id(stack_name, resource)
|
32
32
|
end
|
33
33
|
|
34
34
|
end
|
data/lib/stax/staxfile.rb
CHANGED
@@ -1,20 +1,28 @@
|
|
1
1
|
module Stax
|
2
2
|
@@_stack_list = []
|
3
3
|
|
4
|
+
## list of stacks defined in Staxfile
|
4
5
|
def self.stack_list
|
5
6
|
@@_stack_list
|
6
7
|
end
|
7
8
|
|
9
|
+
## try to require file from lib/stack/ for each stack
|
10
|
+
def self.auto_require(path)
|
11
|
+
stack_list.each do |stack|
|
12
|
+
f = path.join('lib', 'stack', "#{stack}.rb")
|
13
|
+
require(f) if File.exist?(f)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
8
17
|
## search up the dir tree for nearest Staxfile
|
9
18
|
def self.load_staxfile
|
10
|
-
file = nil
|
11
19
|
Pathname.pwd.ascend do |path|
|
12
|
-
if File.exist?(
|
13
|
-
file
|
20
|
+
if File.exist?(file = path.join('Staxfile'))
|
21
|
+
load(file) if file
|
22
|
+
auto_require(path)
|
14
23
|
break
|
15
24
|
end
|
16
25
|
end
|
17
|
-
load(file) if file
|
18
26
|
end
|
19
27
|
|
20
28
|
## add a stack by name, creates class as needed
|
@@ -35,6 +43,8 @@ module Stax
|
|
35
43
|
opt.fetch(:include, []).each do |i|
|
36
44
|
klass.include(self.const_get(i))
|
37
45
|
end
|
46
|
+
|
47
|
+
klass.instance_variable_set(:@imports, Array(opt.fetch(:import, [])))
|
38
48
|
end
|
39
49
|
end
|
40
50
|
|
data/lib/stax/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Lister
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -129,11 +129,12 @@ files:
|
|
129
129
|
- bin/setup
|
130
130
|
- bin/stax
|
131
131
|
- lib/stax.rb
|
132
|
-
- lib/stax/asg.rb
|
133
132
|
- lib/stax/aws/alb.rb
|
134
133
|
- lib/stax/aws/apigw.rb
|
135
134
|
- lib/stax/aws/asg.rb
|
136
135
|
- lib/stax/aws/cfn.rb
|
136
|
+
- lib/stax/aws/codebuild.rb
|
137
|
+
- lib/stax/aws/codepipeline.rb
|
137
138
|
- lib/stax/aws/dynamodb.rb
|
138
139
|
- lib/stax/aws/ec2.rb
|
139
140
|
- lib/stax/aws/ecr.rb
|
@@ -146,6 +147,7 @@ files:
|
|
146
147
|
- lib/stax/aws/kms.rb
|
147
148
|
- lib/stax/aws/lambda.rb
|
148
149
|
- lib/stax/aws/logs.rb
|
150
|
+
- lib/stax/aws/route53.rb
|
149
151
|
- lib/stax/aws/s3.rb
|
150
152
|
- lib/stax/aws/sdk.rb
|
151
153
|
- lib/stax/aws/sg.rb
|
@@ -165,11 +167,15 @@ files:
|
|
165
167
|
- lib/stax/mixin/alb.rb
|
166
168
|
- lib/stax/mixin/apigw.rb
|
167
169
|
- lib/stax/mixin/asg.rb
|
170
|
+
- lib/stax/mixin/codebuild.rb
|
171
|
+
- lib/stax/mixin/codepipeline.rb
|
168
172
|
- lib/stax/mixin/dynamodb.rb
|
169
173
|
- lib/stax/mixin/dynamodb/backup.rb
|
170
174
|
- lib/stax/mixin/dynamodb/throughput.rb
|
171
175
|
- lib/stax/mixin/ec2.rb
|
176
|
+
- lib/stax/mixin/ecr.rb
|
172
177
|
- lib/stax/mixin/ecs.rb
|
178
|
+
- lib/stax/mixin/ecs/deploy.rb
|
173
179
|
- lib/stax/mixin/elb.rb
|
174
180
|
- lib/stax/mixin/emr.rb
|
175
181
|
- lib/stax/mixin/firehose.rb
|
@@ -184,7 +190,9 @@ files:
|
|
184
190
|
- lib/stax/mixin/ssm.rb
|
185
191
|
- lib/stax/stack.rb
|
186
192
|
- lib/stax/stack/cfn.rb
|
193
|
+
- lib/stax/stack/changeset.rb
|
187
194
|
- lib/stax/stack/crud.rb
|
195
|
+
- lib/stax/stack/imports.rb
|
188
196
|
- lib/stax/stack/outputs.rb
|
189
197
|
- lib/stax/stack/parameters.rb
|
190
198
|
- lib/stax/stack/resources.rb
|
@@ -212,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
212
220
|
version: '0'
|
213
221
|
requirements: []
|
214
222
|
rubyforge_project:
|
215
|
-
rubygems_version: 2.
|
223
|
+
rubygems_version: 2.7.3
|
216
224
|
signing_key:
|
217
225
|
specification_version: 4
|
218
226
|
summary: Control Cloudformation stack and other stuff.
|
data/lib/stax/asg.rb
DELETED
@@ -1,140 +0,0 @@
|
|
1
|
-
require 'awful/auto_scaling'
|
2
|
-
|
3
|
-
module Stax
|
4
|
-
module Asg
|
5
|
-
def self.included(thor) # magic to make mixins work in Thor
|
6
|
-
thor.class_eval do # ... so magical
|
7
|
-
|
8
|
-
class_option :groups, aliases: '-g', type: :array, default: nil, desc: 'limit ASGs returned by id'
|
9
|
-
|
10
|
-
no_commands do
|
11
|
-
def auto_scaling_groups
|
12
|
-
cf(:resources, [stack_name], type: ['AWS::AutoScaling::AutoScalingGroup'], quiet: true).tap do |asgs|
|
13
|
-
if options[:groups]
|
14
|
-
ids = options[:groups].map { |group| prepend(:asg, group) }
|
15
|
-
asgs.select! { |g| ids.include?(g.logical_resource_id) }
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def auto_scaling_instances
|
21
|
-
asg(:instances, auto_scaling_groups.map(&:physical_resource_id), describe: true, quiet: true)
|
22
|
-
end
|
23
|
-
|
24
|
-
## get instance details from ec2
|
25
|
-
def auto_scaling_describe_instances
|
26
|
-
asgs = auto_scaling_groups.map(&:physical_resource_id)
|
27
|
-
fail_task("No matching autoscaling groups") if asgs.empty?
|
28
|
-
asg(:ips, auto_scaling_groups.map(&:physical_resource_id), quiet: true)
|
29
|
-
end
|
30
|
-
|
31
|
-
def asg_status
|
32
|
-
auto_scaling_groups.each do |asg|
|
33
|
-
debug("ASG status for #{asg.physical_resource_id}")
|
34
|
-
asg(:instances, [asg.physical_resource_id], long: true)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def asg_enter_standby(asg, *instances)
|
39
|
-
debug("Taking #{instances.join(',')} out of ELB for #{asg}")
|
40
|
-
instances.each do |instance| # one at a time so we can rescue each one
|
41
|
-
begin
|
42
|
-
asg(:enter_standby, [asg, instance])
|
43
|
-
rescue Aws::AutoScaling::Errors::ValidationError => e
|
44
|
-
warn(e.message)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def asg_exit_standby(asg, *instances)
|
50
|
-
debug("Putting #{instances.join(',')} back into ELB")
|
51
|
-
instances.each do |instance| # one at a time so we can rescue each one
|
52
|
-
begin
|
53
|
-
asg(:exit_standby, [asg, instance])
|
54
|
-
rescue Aws::AutoScaling::Errors::ValidationError => e
|
55
|
-
warn(e.message)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
## defaults, override in subclass
|
61
|
-
def ssh_options
|
62
|
-
{
|
63
|
-
User: 'core',
|
64
|
-
StrictHostKeyChecking: 'no',
|
65
|
-
UserKnownHostsFile: '/dev/null'
|
66
|
-
}
|
67
|
-
end
|
68
|
-
|
69
|
-
## return num instances, filter by ids if non-nil
|
70
|
-
def ssh_instances(num, ids)
|
71
|
-
instances = auto_scaling_describe_instances
|
72
|
-
instances.select!{ |i| ids.include?(i.instance_id) } if ids
|
73
|
-
num ? instances.last(num) : instances
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
desc 'scale', 'scale number of instances in ASGs for stack'
|
78
|
-
method_option :desired_capacity, aliases: '-d', type: :numeric, default: nil, desc: 'desired instance count for each ASG'
|
79
|
-
method_option :min_size, aliases: '-m', type: :numeric, default: nil, desc: 'set minimum capacity'
|
80
|
-
method_option :max_size, aliases: '-M', type: :numeric, default: nil, desc: 'set maximum capacity'
|
81
|
-
def scale
|
82
|
-
opt = options.slice(:desired_capacity, :min_size, :max_size)
|
83
|
-
fail_task('No change requested') if opt.empty?
|
84
|
-
|
85
|
-
auto_scaling_groups.tap do |asgs|
|
86
|
-
warn('No matching auto-scaling groups') if asgs.empty?
|
87
|
-
end.each do |asg|
|
88
|
-
id = asg.physical_resource_id
|
89
|
-
debug("Scaling to #{opt} for #{id}")
|
90
|
-
asg(:update, [id], opt)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
desc 'old', 'list or terminate old instances from ASGs'
|
95
|
-
method_option :terminate, aliases: '-t', type: :boolean, default: false, desc: 'terminate old instances'
|
96
|
-
def old
|
97
|
-
verb = options[:terminate] ? 'Terminating' : 'Listing'
|
98
|
-
debug("#{verb} out-of-date instances in autoscaling groups")
|
99
|
-
asgs = auto_scaling_groups.map(&:physical_resource_id)
|
100
|
-
asg(:old_instances, asgs, terminate: options[:terminate])
|
101
|
-
end
|
102
|
-
|
103
|
-
desc 'standby', 'enter (or exit) standby for ASGs'
|
104
|
-
method_option :exit, aliases: '-x', type: :boolean, default: false, desc: 'exit standby instead of enter'
|
105
|
-
def standby
|
106
|
-
auto_scaling_instances.each_with_object(Hash.new {|h,k| h[k]=[]}) do |i, h|
|
107
|
-
h[i.auto_scaling_group_name] << i.instance_id
|
108
|
-
end.each do |asg, ins|
|
109
|
-
options[:exit] ? asg_exit_standby(asg, *ins) : asg_enter_standby(asg, *ins)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
desc 'ssh [CMD]', 'ssh to ASG instances'
|
114
|
-
method_option :number, aliases: '-n', type: :numeric, default: nil, desc: 'number of instances to ssh'
|
115
|
-
method_option :verbose, aliases: '-v', type: :boolean, default: false, desc: 'verbose ssh client logging'
|
116
|
-
method_option :instances, aliases: '-i', type: :array, default: nil, desc: 'match on these instance IDs'
|
117
|
-
def ssh(*cmd)
|
118
|
-
keyfile = try(:key_pair_get) # get private key from param store
|
119
|
-
try(:let_me_in_allow) # open security group
|
120
|
-
|
121
|
-
## build ssh -o options
|
122
|
-
opts = ssh_options.merge(
|
123
|
-
IdentityFile: keyfile.try(:path),
|
124
|
-
LogLevel: (options[:verbose] ? 'DEBUG' : nil)
|
125
|
-
).reject{ |_,v| v.nil? }.map{ |k,v| "-o #{k}=#{v}" }.join(' ')
|
126
|
-
|
127
|
-
## loop instances
|
128
|
-
ssh_instances(options[:number], options[:instances]).each do |i|
|
129
|
-
debug("SSH to #{i.instance_id} #{i.public_ip_address}")
|
130
|
-
system "ssh #{opts} #{i.public_ip_address} #{cmd.join(' ')}"
|
131
|
-
end
|
132
|
-
ensure
|
133
|
-
keyfile.try(:unlink) # remove private key
|
134
|
-
try(:let_me_in_revoke) # close security group
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|