stax 0.1.7 → 0.1.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f2aca89588152ddee959060e8fc3c1dc1bef1c2abb3a57839ab0a35de9aa208
4
- data.tar.gz: b9bcf76bba2aa8a472c07291596142b6d4338a566abd42636fb9cf8b05b6b7be
3
+ metadata.gz: a329f6a9e49e506570e4b869de676c6811be3cb0fc3725107ecd61dbd87574b0
4
+ data.tar.gz: a96ea2c978ceab09a1e9f4686be93d5b96929ef84ac7e2972d437c0283c811fb
5
5
  SHA512:
6
- metadata.gz: b4f6c035f4c10239132e339ef964be95ac86069a47b6bf0f7f1cf7f25a5b1661d3b0d57a518cde8d4ef018d8dd333cc5bfc6b6db6f71e64846b77839bf037958
7
- data.tar.gz: 651280004b99781f0d209b9c91179560b75b238dd0faa1431a6f418f94dc1283e9c06e0a6bb9c9636b847898812f9fa8648f052f47aefbe8230d3cc2c3a33074
6
+ metadata.gz: 71d82f945a2bcd9c9964550ad456714a1f655e6a1df5cbfe19e355b807125306f4e70689ac231344ce55b09dc04d3f248d1c0330939b7f4649817f0a14e879ad
7
+ data.tar.gz: 46a21736e16236d4f415830e4c07f931ff651a0dfc08e1c289e8d6419c5b0af465eef6df9b9d7a79052e4aae40acb447ef3230a2bab17c41bf655d8071ab3a08
data/lib/stax/aws/cfn.rb CHANGED
@@ -17,6 +17,7 @@ module Stax
17
17
  CREATE_COMPLETE: :green,
18
18
  DELETE_COMPLETE: :green,
19
19
  UPDATE_COMPLETE: :green,
20
+ IMPORT_COMPLETE: :green,
20
21
  CREATE_FAILED: :red,
21
22
  DELETE_FAILED: :red,
22
23
  UPDATE_FAILED: :red,
@@ -24,6 +25,7 @@ module Stax
24
25
  ROLLBACK_COMPLETE: :red,
25
26
  ## resource action
26
27
  Add: :green,
28
+ Import: :green,
27
29
  Modify: :yellow,
28
30
  Remove: :red,
29
31
  }
@@ -170,4 +172,4 @@ module Stax
170
172
 
171
173
  end
172
174
  end
173
- end
175
+ end
data/lib/stax/base.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  require 'thor'
2
2
  require 'stax/aws/sts'
3
3
 
4
+ ## clean exit on ctrl-c for all methods
5
+ trap('SIGINT', 'EXIT')
6
+
4
7
  module Stax
5
8
  class Base < Thor
6
9
 
@@ -68,7 +71,9 @@ module Stax
68
71
  end
69
72
  end
70
73
 
71
- def color(string, hash)
74
+ ## color a string according to current class COLORS hash
75
+ def color(string, hash = nil)
76
+ hash ||= self.class::COLORS
72
77
  set_color(string, hash.fetch(string.to_sym, :yellow))
73
78
  end
74
79
 
@@ -118,6 +123,7 @@ module Stax
118
123
 
119
124
  ## convert a diff in seconds to d h m s
120
125
  def human_time_diff(t, n = 5)
126
+ t = t.round # handle fractional seconds
121
127
  mm, ss = t.divmod(60)
122
128
  hh, mm = mm.divmod(60)
123
129
  dd, hh = hh.divmod(24)
@@ -14,6 +14,7 @@ module Stax
14
14
 
15
15
  COLORS = {
16
16
  available: :green,
17
+ 'in-sync': :green,
17
18
  Complete: :green,
18
19
  Active: :green,
19
20
  }
@@ -40,13 +41,36 @@ module Stax
40
41
  def stack_db_subnet_groups
41
42
  Aws::Cfn.resources_by_type(my.stack_name, 'AWS::RDS::DBSubnetGroup')
42
43
  end
44
+
45
+ def print_rds_events(opt)
46
+ Aws::Rds.client.describe_events(opt).map(&:events).flatten.map do |e|
47
+ [ e.date, e.message ]
48
+ end.tap(&method(:print_table))
49
+ end
50
+
51
+ end
52
+
53
+ desc 'ls', 'list clusters with members'
54
+ def ls
55
+ debug("RDS databases for #{my.stack_name}")
56
+ stack_rds_clusters.map do |c|
57
+ cluster = [ c.db_cluster_identifier, 'cluster', color(c.status), c.engine ]
58
+ instances = c.db_cluster_members.map do |m|
59
+ role = m.is_cluster_writer ? 'writer' : 'reader'
60
+ i = Aws::Rds.instances(filters: [ { name: 'db-instance-id', values: [ m.db_instance_identifier ] } ]).first
61
+ [ '- ' + i.db_instance_identifier, role, color(i.db_instance_status), i.engine, i.availability_zone, i.db_instance_class ]
62
+ end
63
+ [ cluster ] + instances
64
+ end.flatten(1).tap do |list|
65
+ print_table list
66
+ end
43
67
  end
44
68
 
45
69
  desc 'clusters', 'list db clusters for stack'
46
70
  def clusters
47
71
  debug("RDS DB clusters for #{my.stack_name}")
48
72
  print_table stack_rds_clusters.map { |c|
49
- [c.db_cluster_identifier, c.engine, c.engine_version, color(c.status, COLORS), c.cluster_create_time]
73
+ [c.db_cluster_identifier, c.engine, c.engine_version, color(c.status), c.cluster_create_time]
50
74
  }
51
75
  end
52
76
 
@@ -65,7 +89,7 @@ module Stax
65
89
  def instances
66
90
  debug("RDS DB instances for #{my.stack_name}")
67
91
  print_table stack_rds_instances.map { |i|
68
- [i.db_instance_identifier, i.engine, i.engine_version, color(i.db_instance_status, COLORS), i.db_instance_class, i.db_subnet_group&.vpc_id, i.availability_zone]
92
+ [i.db_instance_identifier, i.engine, i.engine_version, color(i.db_instance_status), i.db_instance_class, i.db_subnet_group&.vpc_id, i.availability_zone]
69
93
  }
70
94
  end
71
95
 
@@ -92,11 +116,48 @@ module Stax
92
116
  end.flatten.each do |g|
93
117
  debug("Subnets for group #{g.db_subnet_group_name}")
94
118
  print_table g.subnets.map { |s|
95
- [s&.subnet_availability_zone&.name, s&.subnet_identifier, color(s&.subnet_status, COLORS)]
119
+ [s&.subnet_availability_zone&.name, s&.subnet_identifier, color(s&.subnet_status)]
96
120
  }
97
121
  end
98
122
  end
99
123
 
124
+ desc 'failover', 'failover clusters'
125
+ method_option :target, type: :string, default: nil, desc: 'id of instance to promote'
126
+ def failover
127
+ stack_rds_clusters.each do |c|
128
+ if yes?("Failover #{c.db_cluster_identifier}?", :yellow)
129
+ resp = Aws::Rds.client.failover_db_cluster(db_cluster_identifier: c.db_cluster_identifier, target_db_instance_identifier: options[:target])
130
+ puts "failing over #{resp.db_cluster.db_cluster_identifier}"
131
+ end
132
+ end
133
+ end
134
+
135
+ desc 'snapshots', 'list snapshots for stack clusters'
136
+ def snapshots
137
+ stack_db_clusters.map(&:physical_resource_id).each do |id|
138
+ debug("Snapshots for cluster #{id}")
139
+ Aws::Rds.client.describe_db_cluster_snapshots(db_cluster_identifier: id).map(&:db_cluster_snapshots).flatten.map do |s|
140
+ [ s.db_cluster_snapshot_identifier, s.snapshot_create_time, "#{s.allocated_storage}G", color(s.status), s.snapshot_type ]
141
+ end.tap do |list|
142
+ print_table list
143
+ end
144
+ end
145
+ end
146
+
147
+ desc 'events', 'list rds events for this stack'
148
+ option :duration, aliases: '-d', type: :numeric, default: 60*24, desc: 'duration in mins to show'
149
+ def events
150
+ stack_db_clusters.map(&:physical_resource_id).each do |id|
151
+ debug("Events for cluster #{id}")
152
+ print_rds_events(duration: options[:duration], source_type: 'db-cluster', source_identifier: id)
153
+ end
154
+
155
+ stack_db_instances.map(&:physical_resource_id).each do |id|
156
+ debug("Events for instance #{id}")
157
+ print_rds_events(duration: options[:duration], source_type: 'db-instance', source_identifier: id)
158
+ end
159
+ end
160
+
100
161
  end
101
162
  end
102
- end
163
+ end
@@ -30,6 +30,23 @@ module Stax
30
30
  fail_task(e.message)
31
31
  end
32
32
 
33
+ ## create change set to import a resource
34
+ def change_set_import(resource)
35
+ Aws::Cfn.changeset(
36
+ change_set_type: :IMPORT,
37
+ resources_to_import: [ resource ],
38
+ stack_name: stack_name,
39
+ template_body: cfn_template_body,
40
+ template_url: cfn_template_url,
41
+ parameters: cfn_parameters_update,
42
+ capabilities: cfn_capabilities,
43
+ notification_arns: cfn_notification_arns,
44
+ change_set_name: change_set_name,
45
+ ).id
46
+ rescue ::Aws::CloudFormation::Errors::ValidationError => e
47
+ fail_task(e.message)
48
+ end
49
+
33
50
  ## wait and return true if changeset ready for execute
34
51
  def change_set_complete?(id)
35
52
  begin
@@ -94,5 +111,32 @@ module Stax
94
111
  change_set_lock
95
112
  end
96
113
 
114
+ desc 'import', 'create and execute changeset to import a resource'
115
+ option :type, aliases: '-t', type: :string, default: nil, desc: 'cfn resource (e.g. AWS::DynamoDB::Table)'
116
+ option :id, aliases: '-i', type: :string, default: nil, desc: 'logical id (e.g. OrdersTable)'
117
+ option :key, aliases: '-k', type: :string, default: nil, desc: 'resource key (e.g. TableName)'
118
+ option :value, aliases: '-v', type: :string, default: nil, desc: 'resource value (e.g. orders)'
119
+ def import
120
+ ## prompt for missing options
121
+ %i[type id key value].each do |opt|
122
+ options[opt] ||= ask("Resource #{opt}?", :yellow)
123
+ end
124
+
125
+ ## create import changeset
126
+ debug("Creating import change set for #{stack_name}")
127
+ id = change_set_import(
128
+ resource_type: options[:type],
129
+ logical_resource_id: options[:id],
130
+ resource_identifier: {
131
+ options[:key] => options[:value]
132
+ }
133
+ )
134
+
135
+ ## wait for changeset, prompt for changes, and execute
136
+ change_set_complete?(id) || fail_task(change_set_reason(id))
137
+ change_set_changes(id)
138
+ change_set_execute(id) && tail && update_warn_imports
139
+ end
140
+
97
141
  end
98
142
  end
@@ -21,8 +21,8 @@ module Stax
21
21
  end
22
22
  end
23
23
 
24
- desc 'imports', 'list imports from this stack'
25
- def imports
24
+ desc 'exports', 'list exports from this stack, and stacks that import them'
25
+ def exports
26
26
  debug("Stacks that import from #{stack_name}")
27
27
  print_table Aws::Cfn.exports(stack_name).map { |e|
28
28
  imports = (i = Aws::Cfn.imports(e.export_name)).empty? ? '-' : i.join(' ')
@@ -30,5 +30,11 @@ module Stax
30
30
  }.sort
31
31
  end
32
32
 
33
+ desc 'imports', 'deprecated: use exports'
34
+ def imports
35
+ warn("deprecated method: please use 'exports' instead")
36
+ exports
37
+ end
38
+
33
39
  end
34
- end
40
+ end
data/lib/stax/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Stax
2
- VERSION = '0.1.7'
2
+ VERSION = '0.1.8'
3
3
  end
data/lib/stax.rb CHANGED
@@ -16,7 +16,7 @@ require 'stax/stack/crud'
16
16
  require 'stax/stack/changeset'
17
17
  require 'stax/stack/parameters'
18
18
  require 'stax/stack/outputs'
19
- require 'stax/stack/imports'
19
+ require 'stax/stack/exports'
20
20
  require 'stax/stack/resources'
21
21
  require 'stax/stack/drift'
22
22
 
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.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Lister
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-29 00:00:00.000000000 Z
11
+ date: 2021-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -582,7 +582,7 @@ files:
582
582
  - lib/stax/stack/changeset.rb
583
583
  - lib/stax/stack/crud.rb
584
584
  - lib/stax/stack/drift.rb
585
- - lib/stax/stack/imports.rb
585
+ - lib/stax/stack/exports.rb
586
586
  - lib/stax/stack/outputs.rb
587
587
  - lib/stax/stack/parameters.rb
588
588
  - lib/stax/stack/resources.rb