ecs_autoscaling_scheduler 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 91c16cfe5a2d8c2ba3c4abc54eb44bcbd40c3cc1c7f3c44ed6fb2c7988df7544
4
+ data.tar.gz: 100af8f8b90585cea334c1cc16e24c826ea938797d59781d2e723cd7909c790b
5
+ SHA512:
6
+ metadata.gz: f3b22b22059cac484bfe7ebcf3fdd375711336936c1c91252b14d4eb944d5e37213891f1371e7f67c7db5374aa5230d96580f78b3e06078b011f366634ef4646
7
+ data.tar.gz: 92f56ba9a7563ce49ffe7c21946bec22e620a1169392e92d59c0891a72aa822887ba465d08eee6f032fa8e8c24ba18f1fff625bbc4c682f9a08a61e78687ec31
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,6 @@
1
+ inherit_gem:
2
+ rubocop-rails_config:
3
+ - config/rails.yml
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.6
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2022-08-09
4
+
5
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in ecs_autoscaling_scheduler.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rspec", "~> 3.0"
11
+
12
+ gem "rubocop", "~> 1.21"
data/Gemfile.lock ADDED
@@ -0,0 +1,161 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ecs_autoscaling_scheduler (0.1.0)
5
+ activesupport (~> 6.1)
6
+ aws-sdk-applicationautoscaling (~> 1.62)
7
+ aws-sdk-ecs (~> 1.100)
8
+ tty-prompt (~> 0.23)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ actionpack (6.1.6.1)
14
+ actionview (= 6.1.6.1)
15
+ activesupport (= 6.1.6.1)
16
+ rack (~> 2.0, >= 2.0.9)
17
+ rack-test (>= 0.6.3)
18
+ rails-dom-testing (~> 2.0)
19
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
20
+ actionview (6.1.6.1)
21
+ activesupport (= 6.1.6.1)
22
+ builder (~> 3.1)
23
+ erubi (~> 1.4)
24
+ rails-dom-testing (~> 2.0)
25
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
26
+ activesupport (6.1.6.1)
27
+ concurrent-ruby (~> 1.0, >= 1.0.2)
28
+ i18n (>= 1.6, < 2)
29
+ minitest (>= 5.1)
30
+ tzinfo (~> 2.0)
31
+ zeitwerk (~> 2.3)
32
+ ast (2.4.2)
33
+ aws-eventstream (1.2.0)
34
+ aws-partitions (1.616.0)
35
+ aws-sdk-applicationautoscaling (1.62.0)
36
+ aws-sdk-core (~> 3, >= 3.127.0)
37
+ aws-sigv4 (~> 1.1)
38
+ aws-sdk-core (3.132.0)
39
+ aws-eventstream (~> 1, >= 1.0.2)
40
+ aws-partitions (~> 1, >= 1.525.0)
41
+ aws-sigv4 (~> 1.1)
42
+ jmespath (~> 1, >= 1.6.1)
43
+ aws-sdk-ecs (1.100.0)
44
+ aws-sdk-core (~> 3, >= 3.127.0)
45
+ aws-sigv4 (~> 1.1)
46
+ aws-sigv4 (1.5.1)
47
+ aws-eventstream (~> 1, >= 1.0.2)
48
+ builder (3.2.4)
49
+ concurrent-ruby (1.1.10)
50
+ crass (1.0.6)
51
+ diff-lcs (1.5.0)
52
+ erubi (1.11.0)
53
+ i18n (1.12.0)
54
+ concurrent-ruby (~> 1.0)
55
+ jmespath (1.6.1)
56
+ json (2.6.2)
57
+ loofah (2.18.0)
58
+ crass (~> 1.0.2)
59
+ nokogiri (>= 1.5.9)
60
+ method_source (1.0.0)
61
+ minitest (5.16.2)
62
+ nokogiri (1.13.8-arm64-darwin)
63
+ racc (~> 1.4)
64
+ parallel (1.22.1)
65
+ parser (3.1.2.1)
66
+ ast (~> 2.4.1)
67
+ pastel (0.8.0)
68
+ tty-color (~> 0.5)
69
+ racc (1.6.0)
70
+ rack (2.2.4)
71
+ rack-test (2.0.2)
72
+ rack (>= 1.3)
73
+ rails-dom-testing (2.0.3)
74
+ activesupport (>= 4.2.0)
75
+ nokogiri (>= 1.6)
76
+ rails-html-sanitizer (1.4.3)
77
+ loofah (~> 2.3)
78
+ railties (6.1.6.1)
79
+ actionpack (= 6.1.6.1)
80
+ activesupport (= 6.1.6.1)
81
+ method_source
82
+ rake (>= 12.2)
83
+ thor (~> 1.0)
84
+ rainbow (3.1.1)
85
+ rake (13.0.6)
86
+ regexp_parser (2.5.0)
87
+ rexml (3.2.5)
88
+ rspec (3.11.0)
89
+ rspec-core (~> 3.11.0)
90
+ rspec-expectations (~> 3.11.0)
91
+ rspec-mocks (~> 3.11.0)
92
+ rspec-core (3.11.0)
93
+ rspec-support (~> 3.11.0)
94
+ rspec-expectations (3.11.0)
95
+ diff-lcs (>= 1.2.0, < 2.0)
96
+ rspec-support (~> 3.11.0)
97
+ rspec-mocks (3.11.1)
98
+ diff-lcs (>= 1.2.0, < 2.0)
99
+ rspec-support (~> 3.11.0)
100
+ rspec-support (3.11.0)
101
+ rubocop (1.33.0)
102
+ json (~> 2.3)
103
+ parallel (~> 1.10)
104
+ parser (>= 3.1.0.0)
105
+ rainbow (>= 2.2.2, < 4.0)
106
+ regexp_parser (>= 1.8, < 3.0)
107
+ rexml (>= 3.2.5, < 4.0)
108
+ rubocop-ast (>= 1.19.1, < 2.0)
109
+ ruby-progressbar (~> 1.7)
110
+ unicode-display_width (>= 1.4.0, < 3.0)
111
+ rubocop-ast (1.21.0)
112
+ parser (>= 3.1.1.0)
113
+ rubocop-minitest (0.21.0)
114
+ rubocop (>= 0.90, < 2.0)
115
+ rubocop-packaging (0.5.1)
116
+ rubocop (>= 0.89, < 2.0)
117
+ rubocop-performance (1.14.3)
118
+ rubocop (>= 1.7.0, < 2.0)
119
+ rubocop-ast (>= 0.4.0)
120
+ rubocop-rails (2.15.2)
121
+ activesupport (>= 4.2.0)
122
+ rack (>= 1.1)
123
+ rubocop (>= 1.7.0, < 2.0)
124
+ rubocop-rails_config (1.10.4)
125
+ railties (>= 5.0)
126
+ rubocop (>= 1.29.0)
127
+ rubocop-ast (>= 1.0.1)
128
+ rubocop-minitest (~> 0.15)
129
+ rubocop-packaging (~> 0.5)
130
+ rubocop-performance (~> 1.11)
131
+ rubocop-rails (~> 2.0)
132
+ ruby-progressbar (1.11.0)
133
+ thor (1.2.1)
134
+ tty-color (0.6.0)
135
+ tty-cursor (0.7.1)
136
+ tty-prompt (0.23.1)
137
+ pastel (~> 0.8)
138
+ tty-reader (~> 0.8)
139
+ tty-reader (0.9.0)
140
+ tty-cursor (~> 0.7)
141
+ tty-screen (~> 0.8)
142
+ wisper (~> 2.0)
143
+ tty-screen (0.8.1)
144
+ tzinfo (2.0.5)
145
+ concurrent-ruby (~> 1.0)
146
+ unicode-display_width (2.2.0)
147
+ wisper (2.0.1)
148
+ zeitwerk (2.6.0)
149
+
150
+ PLATFORMS
151
+ arm64-darwin-21
152
+
153
+ DEPENDENCIES
154
+ ecs_autoscaling_scheduler!
155
+ rake (~> 13.0)
156
+ rspec (~> 3.0)
157
+ rubocop (~> 1.21)
158
+ rubocop-rails_config
159
+
160
+ BUNDLED WITH
161
+ 2.2.32
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 megane42
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # EcsAutoscalingScheduler
2
+
3
+ ![screen](https://user-images.githubusercontent.com/8451003/183574722-93d2c31d-c5af-4fb0-a1a1-9099088c72b8.gif)
4
+
5
+ ## Requirements
6
+
7
+ - Do `aws configure`
8
+ - https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html
9
+ - Register your ECS service as a scalable target
10
+ - https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/register-scalable-target.html
11
+
12
+ ## Installation
13
+
14
+ ```ruby
15
+ gem 'ecs_autoscaling_scheduler'
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ```
21
+ AWS_PROFILE=foo ecs_autoscaling_scheduler
22
+ ```
23
+
24
+ ## Motivations
25
+
26
+ - At this time, we can configure "target-tracking scaling" or "step scaling" for your ECS service through the AWS Management Console or copilot-cli, but somehow can not configure "scheduled scaling" (even though they have APIs to set up scheduled scaling).
27
+ - Target-tracking scaling or step scaling is not enough for a spike access.
28
+
29
+ ## Development
30
+
31
+ - Check current behavior from console
32
+ - `bin/console`
33
+ - Check current behavior as entire gem
34
+ - `bin/run`
35
+ - Release
36
+ - `emacs CHANGELOG.md` (see https://keepachangelog.com/en/1.0.0/)
37
+ - `emacs lib/ecs_autoscaling_scheduler/version.rb`
38
+ - `bundle exec rake release`
39
+
40
+ ## Contributing
41
+
42
+ Bug reports and pull requests are welcome on GitHub at https://github.com/megane42/ecs_autoscaling_scheduler.
43
+
44
+ ## License
45
+
46
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "ecs_autoscaling_scheduler"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/run ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "ecs_autoscaling_scheduler"
6
+
7
+ EcsAutoscalingScheduler::Cli.new.run
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "ecs_autoscaling_scheduler"
5
+
6
+ EcsAutoscalingScheduler::Cli.new.run
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "aws-sdk-applicationautoscaling"
4
+
5
+ module EcsAutoscalingScheduler
6
+ module Aws
7
+ class ApplicationAutoScaling
8
+ def initialize(client: ::Aws::ApplicationAutoScaling::Client.new)
9
+ @client = client
10
+ end
11
+
12
+ def describe_scheduled_actions(cluster_name:, service_name:)
13
+ client.describe_scheduled_actions(
14
+ {
15
+ service_namespace: "ecs",
16
+ resource_id: resource_id(cluster_name: cluster_name, service_name: service_name),
17
+ }
18
+ ).scheduled_actions
19
+ end
20
+
21
+ def put_scheduled_action(cluster_name:, service_name:, scheduled_action_name:, schedule_datetime:, timezone:, min_capacity:, max_capacity:)
22
+ client.put_scheduled_action(
23
+ {
24
+ service_namespace: "ecs",
25
+ scalable_dimension: "ecs:service:DesiredCount",
26
+ scheduled_action_name: scheduled_action_name,
27
+ schedule: "at(#{schedule_datetime.strftime("%FT%T")})",
28
+ timezone: timezone,
29
+ scalable_target_action: {
30
+ min_capacity: min_capacity,
31
+ max_capacity: max_capacity,
32
+ },
33
+ resource_id: resource_id(cluster_name: cluster_name, service_name: service_name),
34
+ }
35
+ )
36
+ end
37
+
38
+ def delete_scheduled_action(cluster_name:, service_name:, scheduled_action_name:)
39
+ client.delete_scheduled_action(
40
+ {
41
+ service_namespace: "ecs",
42
+ scalable_dimension: "ecs:service:DesiredCount",
43
+ scheduled_action_name: scheduled_action_name,
44
+ resource_id: resource_id(cluster_name: cluster_name, service_name: service_name),
45
+ }
46
+ )
47
+ end
48
+
49
+ private
50
+ attr_reader :client
51
+
52
+ def resource_id(cluster_name:, service_name:)
53
+ "service/#{cluster_name}/#{service_name}"
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "aws-sdk-ecs"
4
+
5
+ module EcsAutoscalingScheduler
6
+ module Aws
7
+ class Ecs
8
+ def initialize(client: ::Aws::ECS::Client.new)
9
+ @client = client
10
+ end
11
+
12
+ def all_cluster_names
13
+ cluster_arns = client.list_clusters.cluster_arns
14
+ client.describe_clusters(clusters: cluster_arns).clusters.map(&:cluster_name)
15
+ end
16
+
17
+ def all_service_names(cluster:)
18
+ service_arns = client.list_services(cluster: cluster).service_arns
19
+ client.describe_services(cluster: cluster, services: service_arns).services.map(&:service_name)
20
+ end
21
+
22
+ private
23
+ attr_reader :client
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "aws/application_auto_scaling"
4
+ require_relative "aws/ecs"
5
+
6
+ module EcsAutoscalingScheduler
7
+ module Aws
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tty-prompt"
4
+
5
+ module EcsAutoscalingScheduler
6
+ class Cli
7
+ class Bye
8
+ def run
9
+ puts "bye."
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tty-prompt"
4
+ require "active_support"
5
+ require "active_support/time"
6
+
7
+ module EcsAutoscalingScheduler
8
+ class Cli
9
+ class Create
10
+ def run
11
+ cluster_name = ask_cluster_name
12
+ service_name = ask_service_name(cluster_name)
13
+ timezone = ask_timezone
14
+ schedule = ask_schedule
15
+ min_capacity = ask_min_capacity
16
+ max_capacity = ask_max_capacity
17
+ scheduled_action_name = ask_scheduled_action_name(schedule, min_capacity, max_capacity)
18
+
19
+ if ask_ok
20
+ application_auto_scaling_client.put_scheduled_action(
21
+ cluster_name: cluster_name,
22
+ service_name: service_name,
23
+ scheduled_action_name: scheduled_action_name,
24
+ schedule_datetime: schedule,
25
+ timezone: timezone,
26
+ min_capacity: min_capacity,
27
+ max_capacity: max_capacity,
28
+ )
29
+ puts "Create complete."
30
+ else
31
+ puts "Create cancelled."
32
+ end
33
+ end
34
+
35
+ private
36
+ def prompt
37
+ @prompt ||= TTY::Prompt.new(interrupt: :signal)
38
+ end
39
+
40
+ def ecs_client
41
+ @ecs_client ||= EcsAutoscalingScheduler::Aws::Ecs.new
42
+ end
43
+
44
+ def application_auto_scaling_client
45
+ @application_auto_scaling_client ||= EcsAutoscalingScheduler::Aws::ApplicationAutoScaling.new
46
+ end
47
+
48
+ def ask_cluster_name
49
+ prompt.select("Which cluster do you want to scale?", ecs_client.all_cluster_names, required: true)
50
+ end
51
+
52
+ def ask_service_name(cluster)
53
+ prompt.select("Which service do you want to scale?", ecs_client.all_service_names(cluster: cluster), required: true)
54
+ end
55
+
56
+ def ask_timezone
57
+ prompt.ask("What is your time zone? (use 'Canonical ID' of https://www.joda.org/joda-time/timezones.html)", default: guess_timezone_name, required: true)
58
+ end
59
+
60
+ def ask_schedule
61
+ prompt.ask("What time do you want to scale? (YYYY-MM-DD hh:mm:ss)", required: true, convert: :time)
62
+ end
63
+
64
+ def ask_min_capacity
65
+ prompt.ask("What is the MIN capacity?", required: true)
66
+ end
67
+
68
+ def ask_max_capacity
69
+ prompt.ask("What is the MAX capacity?", required: true)
70
+ end
71
+
72
+ def ask_scheduled_action_name(schedule, min_capacity, max_capacity)
73
+ prompt.ask("What is the name of the scheduled action?", default: "#{schedule.strftime('%Y%m%d-%H%M%S')}-min-#{min_capacity}-max-#{max_capacity}", required: true)
74
+ end
75
+
76
+ def ask_ok
77
+ prompt.yes?("Do you want to create this scheduled action?", required: true)
78
+ end
79
+
80
+ def guess_timezone_name
81
+ # https://github.com/rails/rails/blob/v6.0.2.1/railties/lib/rails/tasks/misc.rake#L41-L51
82
+ # https://blog.onk.ninja/2020/01/31/guess_local_timezone
83
+ jan_offset = Time.now.beginning_of_year.utc_offset
84
+ jul_offset = Time.now.beginning_of_year.change(month: 7).utc_offset
85
+ offset = jan_offset < jul_offset ? jan_offset : jul_offset
86
+ ActiveSupport::TimeZone.all.detect { |zone| zone.utc_offset == offset }.tzinfo.name
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tty-prompt"
4
+
5
+ module EcsAutoscalingScheduler
6
+ class Cli
7
+ class Destroy
8
+ def run
9
+ cluster_name = ask_cluster_name
10
+ service_name = ask_service_name(cluster_name)
11
+
12
+ scheduled_action_names = application_auto_scaling_client.describe_scheduled_actions(cluster_name: cluster_name, service_name: service_name).map(&:scheduled_action_name)
13
+ if scheduled_action_names.length == 0
14
+ puts "There is no scheduled action."
15
+ return
16
+ end
17
+
18
+ scheduled_action_name = ask_scheduled_action_name(scheduled_action_names)
19
+
20
+ if ask_ok
21
+ application_auto_scaling_client.delete_scheduled_action(
22
+ cluster_name: cluster_name,
23
+ service_name: service_name,
24
+ scheduled_action_name: scheduled_action_name,
25
+ )
26
+ puts "Destroy complete."
27
+ else
28
+ puts "Destroy cancelled."
29
+ end
30
+ end
31
+
32
+ private
33
+ def prompt
34
+ @prompt ||= TTY::Prompt.new
35
+ end
36
+
37
+ def ecs_client
38
+ @ecs_client ||= EcsAutoscalingScheduler::Aws::Ecs.new
39
+ end
40
+
41
+ def application_auto_scaling_client
42
+ @application_auto_scaling_client ||= EcsAutoscalingScheduler::Aws::ApplicationAutoScaling.new
43
+ end
44
+
45
+ def ask_cluster_name
46
+ prompt.select("Which cluster do you want to manage?", ecs_client.all_cluster_names, required: true)
47
+ end
48
+
49
+ def ask_service_name(cluster)
50
+ prompt.select("Which service do you want to manage?", ecs_client.all_service_names(cluster: cluster), required: true)
51
+ end
52
+
53
+ def ask_scheduled_action_name(scheduled_action_names)
54
+ prompt.select("Which scheduled action do you want to destroy?", scheduled_action_names, required: true)
55
+ end
56
+
57
+ def ask_ok
58
+ prompt.yes?("Do you want to destroy this scheduled action?", required: true)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tty-prompt"
4
+
5
+ module EcsAutoscalingScheduler
6
+ class Cli
7
+ class Index
8
+ def run
9
+ cluster_name = ask_cluster_name
10
+ service_name = ask_service_name(cluster_name)
11
+
12
+ scheduled_actions = application_auto_scaling_client.describe_scheduled_actions(
13
+ cluster_name: cluster_name,
14
+ service_name: service_name,
15
+ )
16
+
17
+ scheduled_actions.sort_by(&:schedule).each do |a|
18
+ puts "* name: #{a.scheduled_action_name}, min: #{a.scalable_target_action.min_capacity}, max: #{a.scalable_target_action.max_capacity}, schedule: #{a.schedule}, timezone: #{a.timezone}"
19
+ end
20
+ end
21
+
22
+ private
23
+ def prompt
24
+ @prompt ||= TTY::Prompt.new
25
+ end
26
+
27
+ def ecs_client
28
+ @ecs_client ||= EcsAutoscalingScheduler::Aws::Ecs.new
29
+ end
30
+
31
+ def application_auto_scaling_client
32
+ @application_auto_scaling_client ||= EcsAutoscalingScheduler::Aws::ApplicationAutoScaling.new
33
+ end
34
+
35
+ def ask_cluster_name
36
+ prompt.select("Which cluster do you want to see?", ecs_client.all_cluster_names, required: true)
37
+ end
38
+
39
+ def ask_service_name(cluster)
40
+ prompt.select("Which service do you want to see?", ecs_client.all_service_names(cluster: cluster), required: true)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "cli/index"
4
+ require_relative "cli/create"
5
+ require_relative "cli/destroy"
6
+ require_relative "cli/bye"
7
+
8
+ require "tty-prompt"
9
+
10
+ module EcsAutoscalingScheduler
11
+ class Cli
12
+ COMMAND = {
13
+ index: "index",
14
+ create: "create",
15
+ destroy: "destroy",
16
+ bye: "bye",
17
+ }
18
+
19
+ def run
20
+ case ask_command
21
+ when COMMAND[:index]
22
+ Index.new.run
23
+ when COMMAND[:create]
24
+ Create.new.run
25
+ when COMMAND[:destroy]
26
+ Destroy.new.run
27
+ else
28
+ Bye.new.run
29
+ end
30
+ end
31
+
32
+ private
33
+ def prompt
34
+ @prompt ||= TTY::Prompt.new
35
+ end
36
+
37
+ def ask_command
38
+ prompt.select("Which command do you want to do?", COMMAND.values, required: true)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EcsAutoscalingScheduler
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "ecs_autoscaling_scheduler/version"
4
+ require_relative "ecs_autoscaling_scheduler/aws"
5
+ require_relative "ecs_autoscaling_scheduler/cli"
6
+
7
+ module EcsAutoscalingScheduler
8
+ class Error < StandardError; end
9
+ end
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ecs_autoscaling_scheduler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - megane42
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-08-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-applicationautoscaling
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.62'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.62'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk-ecs
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.100'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.100'
41
+ - !ruby/object:Gem::Dependency
42
+ name: tty-prompt
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.23'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.23'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '6.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '6.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-rails_config
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - ''
86
+ executables:
87
+ - ecs_autoscaling_scheduler
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".rspec"
92
+ - ".rubocop.yml"
93
+ - CHANGELOG.md
94
+ - Gemfile
95
+ - Gemfile.lock
96
+ - LICENSE.txt
97
+ - README.md
98
+ - Rakefile
99
+ - bin/console
100
+ - bin/run
101
+ - bin/setup
102
+ - exe/ecs_autoscaling_scheduler
103
+ - lib/ecs_autoscaling_scheduler.rb
104
+ - lib/ecs_autoscaling_scheduler/aws.rb
105
+ - lib/ecs_autoscaling_scheduler/aws/application_auto_scaling.rb
106
+ - lib/ecs_autoscaling_scheduler/aws/ecs.rb
107
+ - lib/ecs_autoscaling_scheduler/cli.rb
108
+ - lib/ecs_autoscaling_scheduler/cli/bye.rb
109
+ - lib/ecs_autoscaling_scheduler/cli/create.rb
110
+ - lib/ecs_autoscaling_scheduler/cli/destroy.rb
111
+ - lib/ecs_autoscaling_scheduler/cli/index.rb
112
+ - lib/ecs_autoscaling_scheduler/version.rb
113
+ homepage: https://github.com/megane42/ecs_autoscaling_scheduler/
114
+ licenses:
115
+ - MIT
116
+ metadata:
117
+ allowed_push_host: https://rubygems.org
118
+ homepage_uri: https://github.com/megane42/ecs_autoscaling_scheduler/
119
+ source_code_uri: https://github.com/megane42/ecs_autoscaling_scheduler/
120
+ changelog_uri: https://github.com/megane42/ecs_autoscaling_scheduler/blob/master/CHANGELOG.md
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: 2.6.0
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubygems_version: 3.0.3.1
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: A CLI to manage scheduled scaling for ECS services
140
+ test_files: []