ecs_deploy_cli 0.1.0 → 0.4.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ecs_deploy_cli.rb +5 -1
  3. data/lib/ecs_deploy_cli/cli.rb +40 -2
  4. data/lib/ecs_deploy_cli/cloudformation/default.yml +411 -0
  5. data/lib/ecs_deploy_cli/dsl/auto_options.rb +17 -1
  6. data/lib/ecs_deploy_cli/dsl/cluster.rb +70 -0
  7. data/lib/ecs_deploy_cli/dsl/container.rb +8 -10
  8. data/lib/ecs_deploy_cli/dsl/parser.rb +9 -5
  9. data/lib/ecs_deploy_cli/dsl/service.rb +31 -2
  10. data/lib/ecs_deploy_cli/dsl/task.rb +2 -0
  11. data/lib/ecs_deploy_cli/runner.rb +26 -125
  12. data/lib/ecs_deploy_cli/runners/base.rb +105 -0
  13. data/lib/ecs_deploy_cli/runners/diff.rb +74 -0
  14. data/lib/ecs_deploy_cli/runners/logs.rb +14 -0
  15. data/lib/ecs_deploy_cli/runners/run_task.rb +27 -0
  16. data/lib/ecs_deploy_cli/runners/setup.rb +128 -0
  17. data/lib/ecs_deploy_cli/runners/ssh.rb +79 -0
  18. data/lib/ecs_deploy_cli/runners/status.rb +23 -0
  19. data/lib/ecs_deploy_cli/runners/update_crons.rb +41 -0
  20. data/lib/ecs_deploy_cli/runners/update_services.rb +55 -0
  21. data/lib/ecs_deploy_cli/runners/validate.rb +47 -0
  22. data/lib/ecs_deploy_cli/version.rb +3 -1
  23. data/spec/ecs_deploy_cli/cli_spec.rb +44 -4
  24. data/spec/ecs_deploy_cli/dsl/cluster_spec.rb +48 -0
  25. data/spec/ecs_deploy_cli/dsl/container_spec.rb +6 -4
  26. data/spec/ecs_deploy_cli/dsl/cron_spec.rb +2 -0
  27. data/spec/ecs_deploy_cli/dsl/parser_spec.rb +2 -0
  28. data/spec/ecs_deploy_cli/dsl/service_spec.rb +31 -0
  29. data/spec/ecs_deploy_cli/dsl/task_spec.rb +2 -0
  30. data/spec/ecs_deploy_cli/runner_spec.rb +177 -26
  31. data/spec/ecs_deploy_cli/runners/base_spec.rb +57 -0
  32. data/spec/spec_helper.rb +2 -3
  33. data/spec/support/ECSFile +13 -1
  34. data/spec/support/ECSFile.minimal +12 -0
  35. metadata +104 -13
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EcsDeployCli
4
+ module Runners
5
+ class Validate < Base
6
+ def run!
7
+ services, _, crons = @parser.resolve
8
+
9
+ validate_cluster!
10
+ validate_services!(services)
11
+ validate_crons!(crons)
12
+ end
13
+
14
+ private
15
+
16
+ def validate_cluster!
17
+ data = ecs_client.describe_clusters(clusters: [config[:cluster]])
18
+
19
+ raise "No such cluster #{config[:cluster]}." if data.to_h[:failures]&.any? || data.to_h[:clusters].length == 0
20
+ rescue Aws::ECS::Errors::ClusterNotFoundException
21
+ raise "No such cluster #{config[:cluster]}."
22
+ end
23
+
24
+ def validate_services!(services)
25
+ services&.each do |service_name, _|
26
+ data = ecs_client.describe_services(cluster: config[:cluster], services: [service_name])
27
+
28
+ raise "No such service #{service_name}." if data.to_h[:failures]&.any? || data.to_h[:services].length == 0
29
+ end
30
+ end
31
+
32
+ def validate_crons!(crons)
33
+ crons&.each do |cron_name, _|
34
+ items = cwe_client.list_targets_by_rule(
35
+ {
36
+ rule: cron_name,
37
+ limit: 1
38
+ }
39
+ )
40
+ raise "No such cron #{cron_name}." if items.targets.empty?
41
+ rescue Aws::CloudWatchEvents::Errors::ResourceNotFoundException
42
+ raise "No such cron #{cron_name}."
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EcsDeployCli
2
- VERSION = '0.1.0'
4
+ VERSION = '0.4.0'
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe EcsDeployCli::CLI do
@@ -20,33 +22,71 @@ describe EcsDeployCli::CLI do
20
22
  expect { described_class.start(['version']) }.to output(/Version #{EcsDeployCli::VERSION}/).to_stdout
21
23
  end
22
24
 
25
+ it 'runs diff' do
26
+ expect(runner).to receive(:diff)
27
+ described_class.no_commands do
28
+ expect_any_instance_of(described_class).to receive(:runner).at_least(:once).and_return(runner)
29
+ end
30
+
31
+ described_class.start(['diff', '--file', 'spec/support/ECSFile'])
32
+ end
33
+
23
34
  it 'runs validate' do
35
+ expect(runner).to receive(:validate!)
36
+ described_class.no_commands do
37
+ expect_any_instance_of(described_class).to receive(:runner).at_least(:once).and_return(runner)
38
+ end
24
39
  expect { described_class.start(['validate', '--file', 'spec/support/ECSFile']) }.to output(/Your ECSFile looks fine! 🎉/).to_stdout
25
40
  end
26
41
 
42
+ it 'runs run-task' do
43
+ expect(runner).to receive(:run_task!)
44
+ described_class.no_commands do
45
+ expect_any_instance_of(described_class).to receive(:runner).at_least(:once).and_return(runner)
46
+ end
47
+
48
+ described_class.start(['run-task', 'yourproject', '--subnets', 'subnet-123123', '--file', 'spec/support/ECSFile'])
49
+ end
50
+
51
+ it 'runs setup' do
52
+ expect(runner).to receive(:setup!)
53
+ described_class.no_commands do
54
+ expect_any_instance_of(described_class).to receive(:runner).at_least(:once).and_return(runner)
55
+ end
56
+ expect { described_class.start(['setup', '--file', 'spec/support/ECSFile']) }.to output(/[WARNING]/).to_stdout
57
+ end
58
+
27
59
  it 'runs deploy' do
28
60
  expect(runner).to receive(:update_crons!)
29
61
  expect(runner).to receive(:update_services!).with(timeout: 500)
30
- expect_any_instance_of(described_class).to receive(:runner).at_least(:once).and_return(runner)
62
+ described_class.no_commands do
63
+ expect_any_instance_of(described_class).to receive(:runner).at_least(:once).and_return(runner)
64
+ end
31
65
  expect { described_class.start(['deploy', '--file', 'spec/support/ECSFile']) }.to output(/[WARNING]/).to_stdout
32
66
  end
33
67
 
34
68
  it 'runs deploy-services' do
35
69
  expect(runner).to receive(:update_services!)
36
- expect_any_instance_of(described_class).to receive(:runner).and_return(runner)
70
+ described_class.no_commands do
71
+ expect_any_instance_of(described_class).to receive(:runner).and_return(runner)
72
+ end
37
73
  expect { described_class.start(['deploy-services', '--file', 'spec/support/ECSFile']) }.to output(/[WARNING]/).to_stdout
38
74
  end
39
75
 
40
76
  it 'runs ssh' do
41
77
  expect(runner).to receive(:ssh)
42
- expect_any_instance_of(described_class).to receive(:runner).and_return(runner)
78
+ described_class.no_commands do
79
+ expect_any_instance_of(described_class).to receive(:runner).and_return(runner)
80
+ end
43
81
 
44
82
  described_class.start(['ssh', '--file', 'spec/support/ECSFile'])
45
83
  end
46
84
 
47
85
  it 'runs deploy-scheduled-tasks' do
48
86
  expect(runner).to receive(:update_crons!)
49
- expect_any_instance_of(described_class).to receive(:runner).and_return(runner)
87
+ described_class.no_commands do
88
+ expect_any_instance_of(described_class).to receive(:runner).at_least(:once).and_return(runner)
89
+ end
50
90
 
51
91
  described_class.start(['deploy-scheduled-tasks', '--file', 'spec/support/ECSFile'])
52
92
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe EcsDeployCli::DSL::Cluster do
6
+ context 'defines cluster data' do
7
+ subject { described_class.new('mydata-cluster', { aws_profile_id: '123123', aws_region: 'eu-central-1' }) }
8
+
9
+ it '#vpc' do
10
+ subject.instances_count 1
11
+ subject.instance_type 't2.small'
12
+ subject.keypair_name 'test'
13
+
14
+ subject.vpc do
15
+ cidr '11.0.0.0/16'
16
+ subnet1 '11.0.0.0/24'
17
+ subnet2 '11.0.1.0/24'
18
+ subnet3 '11.0.2.0/24'
19
+ subnet_ids 'subnet-123', 'subnet-321', 'subnet-333'
20
+
21
+ availability_zones 'eu-central-1a', 'eu-central-1b', 'eu-central-1c'
22
+ end
23
+
24
+ expect(subject.as_definition).to eq(
25
+ {
26
+ device_name: '/dev/xvda',
27
+ ebs_volume_size: 22,
28
+ ebs_volume_type: 'gp2',
29
+ instances_count: 1,
30
+ instance_type: 't2.small',
31
+ keypair_name: 'test',
32
+ name: 'mydata-cluster',
33
+ root_device_name: '/dev/xvdcz',
34
+ root_ebs_volume_size: 30,
35
+ vpc: {
36
+ availability_zones: 'eu-central-1a,eu-central-1b,eu-central-1c',
37
+ cidr: '11.0.0.0/16',
38
+ id: nil,
39
+ subnet1: '11.0.0.0/24',
40
+ subnet2: '11.0.1.0/24',
41
+ subnet3: '11.0.2.0/24',
42
+ subnet_ids: 'subnet-123,subnet-321,subnet-333'
43
+ }
44
+ }
45
+ )
46
+ end
47
+ end
48
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe EcsDeployCli::DSL::Container do
@@ -20,10 +22,10 @@ describe EcsDeployCli::DSL::Container do
20
22
  expect(subject.as_definition[:environment]).to eq(
21
23
  [
22
24
  {
23
- 'name' => 'SOME', 'value' => 'env'
25
+ name: 'SOME', value: 'env'
24
26
  },
25
27
  {
26
- 'name' => 'SOME2', 'value' => 'env2'
28
+ name: 'SOME2', value: 'env2'
27
29
  }
28
30
  ]
29
31
  )
@@ -89,10 +91,10 @@ describe EcsDeployCli::DSL::Container do
89
91
  expect(subject.as_definition[:environment]).to eq(
90
92
  [
91
93
  {
92
- 'name' => 'RAILS_ENV', 'value' => 'production'
94
+ name: 'RAILS_ENV', value: 'production'
93
95
  },
94
96
  {
95
- 'name' => 'API_KEY', 'value' => '123123123'
97
+ name: 'API_KEY', value: '123123123'
96
98
  }
97
99
  ]
98
100
  )
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe EcsDeployCli::DSL::Cron do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe EcsDeployCli::DSL::Parser do
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe EcsDeployCli::DSL::Service do
6
+ context 'defines service data' do
7
+ subject { described_class.new('test', { aws_profile_id: '123123', aws_region: 'eu-central-1' }) }
8
+
9
+ it 'has the correct name' do
10
+ expect(subject.as_definition({})[:service]).to eq('test')
11
+ end
12
+
13
+ it '#load_balancer' do
14
+ subject.load_balancer :'yourproject-load-balancer' do
15
+ target_group_arn 'loader-target-group/123abc'
16
+ container_name :web
17
+ container_port 80
18
+ end
19
+
20
+ expect(subject.as_definition({})[:load_balancers]).to eq(
21
+ [
22
+ {
23
+ container_name: :web,
24
+ container_port: 80,
25
+ target_group_arn: 'arn:aws:elasticloadbalancing:eu-central-1:123123:targetgroup/loader-target-group/123abc'
26
+ }
27
+ ]
28
+ )
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe EcsDeployCli::DSL::Task do
@@ -1,19 +1,84 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'aws-sdk-cloudwatchevents'
5
+ require 'aws-sdk-cloudwatchlogs'
3
6
  require 'aws-sdk-ec2'
7
+ require 'aws-sdk-ssm'
8
+ require 'aws-sdk-cloudformation'
4
9
 
5
10
  describe EcsDeployCli::Runner do
6
11
  context 'defines task data' do
7
12
  let(:parser) { EcsDeployCli::DSL::Parser.load('spec/support/ECSFile') }
8
13
  subject { described_class.new(parser) }
14
+ let(:mock_cf_client) { Aws::CloudFormation::Client.new(stub_responses: true) }
15
+ let(:mock_ssm_client) { Aws::SSM::Client.new(stub_responses: true) }
9
16
  let(:mock_ecs_client) { Aws::ECS::Client.new(stub_responses: true) }
10
17
  let(:mock_ec2_client) { Aws::EC2::Client.new(stub_responses: true) }
18
+ let(:mock_cwl_client) { Aws::CloudWatchLogs::Client.new(stub_responses: true) }
11
19
  let(:mock_cwe_client) do
12
20
  Aws::CloudWatchEvents::Client.new(stub_responses: true)
13
21
  end
14
22
 
15
- it '#validate!' do
16
- expect { subject.validate! }.to raise_error('Missing required parameter aws_profile_id')
23
+ context '#validate!' do
24
+ it 'fails on missing params' do
25
+ expect { subject.validate! }.to raise_error('Missing required parameter aws_profile_id')
26
+ end
27
+
28
+ context 'with a minimal set of options' do
29
+ let(:parser) { EcsDeployCli::DSL::Parser.load('spec/support/ECSFile.minimal') }
30
+ it 'fails on missing params' do
31
+ mock_ecs_client.stub_responses(:describe_clusters, { clusters: [{ cluster_arn: 'arn:xxx', cluster_name: 'yourproject-cluster' }] })
32
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
33
+ subject.validate!
34
+ end
35
+ end
36
+
37
+ context 'with envs set' do
38
+ around(:each) do |example|
39
+ ENV['AWS_PROFILE_ID'] = '123123123'
40
+ ENV['AWS_REGION'] = 'us-east-1'
41
+ example.run
42
+ ENV['AWS_PROFILE_ID'] = nil
43
+ ENV['AWS_REGION'] = nil
44
+ end
45
+
46
+ it 'fails on missing cluster' do
47
+ mock_ecs_client.stub_responses(:describe_clusters, { failures: [{ arn: 'arn:xxx', reason: 'MISSING' }] })
48
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
49
+ expect { subject.validate! }.to raise_error('No such cluster yourproject-cluster.')
50
+ end
51
+
52
+ it 'fails on missing service' do
53
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
54
+
55
+ mock_ecs_client.stub_responses(:describe_clusters, { clusters: [{ cluster_arn: 'arn:xxx', cluster_name: 'yourproject-cluster' }] })
56
+ mock_ecs_client.stub_responses(:describe_services, { services: [], failures: [{}] })
57
+
58
+ expect { subject.validate! }.to raise_error('No such service yourproject-service.')
59
+ end
60
+
61
+ it 'fails on missing crons' do
62
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:cwe_client).at_least(:once).and_return(mock_cwe_client)
63
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
64
+
65
+ mock_ecs_client.stub_responses(:describe_clusters, { clusters: [{ cluster_arn: 'arn:xxx', cluster_name: 'yourproject-cluster' }] })
66
+ mock_ecs_client.stub_responses(:describe_services, { services: [{ service_arn: 'arn:xxx', service_name: 'yourproject-service' }] })
67
+
68
+ expect { subject.validate! }.to raise_error('No such cron scheduled_emails.')
69
+ end
70
+
71
+ it 'makes API calls to check if everything is there' do
72
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
73
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:cwe_client).at_least(:once).and_return(mock_cwe_client)
74
+
75
+ mock_ecs_client.stub_responses(:describe_clusters, { clusters: [{ cluster_arn: 'arn:xxx', cluster_name: 'yourproject-cluster' }] })
76
+ mock_cwe_client.stub_responses(:list_targets_by_rule, { targets: [{ id: '123', arn: 'arn:123' }] })
77
+ mock_ecs_client.stub_responses(:describe_services, { services: [{ service_arn: 'arn:xxx', service_name: 'yourproject-service' }] })
78
+
79
+ subject.validate!
80
+ end
81
+ end
17
82
  end
18
83
 
19
84
  context 'with envs set' do
@@ -25,29 +90,109 @@ describe EcsDeployCli::Runner do
25
90
  ENV['AWS_REGION'] = nil
26
91
  end
27
92
 
28
- it '#ssh' do
29
- expect(mock_ecs_client).to receive(:list_container_instances).and_return({ container_instance_arns: ['arn:123123'] })
30
- expect(mock_ecs_client).to receive(:describe_container_instances).and_return(double(container_instances: [double(ec2_instance_id: 'i-123123')]))
31
-
32
- expect(mock_ec2_client).to receive(:describe_instances)
33
- .with(instance_ids: ['i-123123'])
34
- .and_return(
35
- double(reservations: [
36
- double(instances: [double(public_dns_name: 'test.com')])
37
- ]
38
- )
39
- )
40
-
41
- expect(Process).to receive(:fork) do |&block|
42
- block.call
93
+ it '#setup!' do
94
+ mock_ssm_client.stub_responses(:get_parameter, {
95
+ parameter: {
96
+ name: '/aws/service/ecs/optimized-ami/amazon-linux-2/recommended',
97
+ type: 'String',
98
+ value: '{"schema_version":1,"image_name":"amzn2-ami-ecs-hvm-2.0.20210331-x86_64-ebs","image_id":"ami-03bbf53329af34379","os":"Amazon Linux 2","ecs_runtime_version":"Docker version 19.03.13-ce","ecs_agent_version":"1.51.0"}'
99
+ }
100
+ })
101
+
102
+ expect(mock_cf_client).to receive(:wait_until)
103
+ expect(mock_ecs_client).to receive(:create_service)
104
+
105
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:cwl_client).at_least(:once).and_return(mock_cwl_client)
106
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
107
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ssm_client).at_least(:once).and_return(mock_ssm_client)
108
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:cf_client).at_least(:once).and_return(mock_cf_client)
109
+
110
+ subject.setup!
111
+ end
112
+
113
+ context '#ssh' do
114
+ it 'runs ssh on a single container instance' do
115
+ expect(mock_ecs_client).to receive(:list_tasks).and_return({ task_arns: ['arn:123123'] })
116
+ expect(mock_ecs_client).to receive(:describe_tasks).and_return({ tasks: [{ container_instance_arn: 'arn:instance:123123' }] })
117
+ expect(mock_ecs_client).to receive(:describe_container_instances).and_return(double(container_instances: [double(ec2_instance_id: 'i-123123')]))
118
+
119
+ expect(mock_ec2_client).to receive(:describe_instances)
120
+ .with(instance_ids: ['i-123123'])
121
+ .and_return(
122
+ double(reservations: [
123
+ double(instances: [double(public_dns_name: 'test.com')])
124
+ ])
125
+ )
126
+
127
+ expect(Process).to receive(:fork) do |&block|
128
+ block.call
129
+ end
130
+ expect(Process).to receive(:wait)
131
+
132
+ expect_any_instance_of(EcsDeployCli::Runners::SSH).to receive(:exec).with('ssh ec2-user@test.com')
133
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
134
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ec2_client).at_least(:once).and_return(mock_ec2_client)
135
+
136
+ subject.ssh
43
137
  end
44
- expect(Process).to receive(:wait)
45
138
 
46
- expect(subject).to receive(:exec).with('ssh ec2-user@test.com')
47
- expect(subject).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
48
- expect(subject).to receive(:ec2_client).at_least(:once).and_return(mock_ec2_client)
139
+ it 'prompts which instance if there are multiple ones' do
140
+ expect(mock_ecs_client).to receive(:list_tasks).and_return({ task_arns: ['arn:123123', 'arn:321321'] })
141
+ expect(mock_ecs_client).to receive(:describe_tasks).and_return(
142
+ {
143
+ tasks: [
144
+ { container_instance_arn: 'arn:instance:123123' },
145
+ { container_instance_arn: 'arn:instance:321321' }
146
+ ]
147
+ }
148
+ )
149
+ expect(mock_ecs_client).to receive(:describe_container_instances).and_return(
150
+ double(container_instances: [double(ec2_instance_id: 'i-123123'), double(ec2_instance_id: 'i-321321')])
151
+ )
152
+
153
+ expect(STDIN).to receive(:gets).and_return('2')
154
+
155
+ expect(mock_ec2_client).to receive(:describe_instances)
156
+ .with(instance_ids: ['i-321321'])
157
+ .and_return(
158
+ double(reservations: [
159
+ double(instances: [double(public_dns_name: 'test.com')])
160
+ ])
161
+ )
162
+
163
+ expect(Process).to receive(:fork) do |&block|
164
+ block.call
165
+ end
166
+ expect(Process).to receive(:wait)
167
+
168
+ expect_any_instance_of(EcsDeployCli::Runners::SSH).to receive(:exec).with('ssh ec2-user@test.com')
169
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
170
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ec2_client).at_least(:once).and_return(mock_ec2_client)
171
+
172
+ subject.ssh
173
+ end
174
+ end
175
+
176
+ it '#diff' do
177
+ mock_ecs_client.stub_responses(:describe_task_definition)
178
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
179
+
180
+ expect(EcsDeployCli.logger).to receive(:info).at_least(:once) do |message|
181
+ puts message
182
+ end
183
+
184
+ expect { subject.diff }.to output(/Task: yourproject/).to_stdout
185
+ end
186
+
187
+ it '#run_task!' do
188
+ mock_ecs_client.stub_responses(:register_task_definition, { task_definition: { family: 'some', revision: 1, task_definition_arn: 'arn:task:eu-central-1:xxxx' } })
189
+
190
+ mock_cwe_client.stub_responses(:run_task)
191
+
192
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:cwl_client).at_least(:once).and_return(mock_cwl_client)
193
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
49
194
 
50
- subject.ssh
195
+ subject.run_task!('yourproject-cron', launch_type: 'FARGATE', security_groups: [], subnets: [])
51
196
  end
52
197
 
53
198
  it '#update_crons!' do
@@ -55,18 +200,24 @@ describe EcsDeployCli::Runner do
55
200
 
56
201
  mock_cwe_client.stub_responses(:list_targets_by_rule, { targets: [{ id: '123', arn: 'arn:123' }] })
57
202
 
58
- expect(subject).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
59
- expect(subject).to receive(:cwe_client).at_least(:once).and_return(mock_cwe_client)
203
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:cwl_client).at_least(:once).and_return(mock_cwl_client)
204
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
205
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:cwe_client).at_least(:once).and_return(mock_cwe_client)
60
206
 
61
207
  subject.update_crons!
62
208
  end
63
209
 
64
210
  it '#update_services!' do
65
211
  expect(mock_ecs_client).to receive(:register_task_definition).at_least(:once).and_return({ task_definition: { family: 'some', revision: '1' } })
66
- expect(mock_ecs_client).to receive(:update_service)
212
+ expect(mock_ecs_client).to receive(:update_service).with(
213
+ cluster: 'yourproject-cluster',
214
+ service: 'yourproject-service',
215
+ task_definition: 'some:1'
216
+ )
67
217
  expect(mock_ecs_client).to receive(:wait_until)
68
218
 
69
- expect(subject).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
219
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:cwl_client).at_least(:once).and_return(mock_cwl_client)
220
+ expect_any_instance_of(EcsDeployCli::Runners::Base).to receive(:ecs_client).at_least(:once).and_return(mock_ecs_client)
70
221
 
71
222
  subject.update_services!
72
223
  end