aptible-cli 0.18.3 → 0.19.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/README.md +63 -50
- data/lib/aptible/cli/agent.rb +6 -2
- data/lib/aptible/cli/helpers/log_drain.rb +85 -0
- data/lib/aptible/cli/helpers/metric_drain.rb +39 -0
- data/lib/aptible/cli/resource_formatter.rb +43 -3
- data/lib/aptible/cli/subcommands/apps.rb +5 -40
- data/lib/aptible/cli/subcommands/backup.rb +15 -7
- data/lib/aptible/cli/subcommands/db.rb +23 -20
- data/lib/aptible/cli/subcommands/log_drain.rb +159 -0
- data/lib/aptible/cli/subcommands/metric_drain.rb +137 -0
- data/lib/aptible/cli/version.rb +1 -1
- data/spec/aptible/cli/subcommands/apps_spec.rb +0 -47
- data/spec/aptible/cli/subcommands/backup_spec.rb +1 -1
- data/spec/aptible/cli/subcommands/db_spec.rb +0 -26
- data/spec/aptible/cli/subcommands/log_drain_spec.rb +207 -0
- data/spec/aptible/cli/subcommands/metric_drain_spec.rb +183 -0
- data/spec/fabricators/account_fabricator.rb +2 -0
- data/spec/fabricators/log_drain_fabricator.rb +21 -0
- data/spec/fabricators/metric_drain_fabricator.rb +8 -0
- metadata +14 -5
- data/lib/aptible/cli/subcommands/domains.rb +0 -40
- data/spec/aptible/cli/subcommands/domains_spec.rb +0 -76
@@ -57,16 +57,6 @@ describe Aptible::CLI::Agent do
|
|
57
57
|
subject.send('db:create', 'foo')
|
58
58
|
end
|
59
59
|
|
60
|
-
it 'creates a new DB with a (implicitly) disk size' do
|
61
|
-
expect_provision_database(
|
62
|
-
{ handle: 'foo', type: 'postgresql', initial_disk_size: 200 },
|
63
|
-
{ disk_size: 200 }
|
64
|
-
)
|
65
|
-
|
66
|
-
subject.options = { type: 'postgresql', size: 200 }
|
67
|
-
subject.send('db:create', 'foo')
|
68
|
-
end
|
69
|
-
|
70
60
|
it 'creates a new DB with a disk-size' do
|
71
61
|
expect_provision_database(
|
72
62
|
{ handle: 'foo', type: 'postgresql', initial_disk_size: 200 },
|
@@ -414,18 +404,6 @@ describe Aptible::CLI::Agent do
|
|
414
404
|
expect(captured_logs).to match(/restarting foobar/i)
|
415
405
|
end
|
416
406
|
|
417
|
-
it 'allows restarting a database with (implicitly disk) size' do
|
418
|
-
expect(database).to receive(:create_operation!)
|
419
|
-
.with(type: 'restart', disk_size: 40).and_return(op)
|
420
|
-
|
421
|
-
expect(subject).to receive(:attach_to_operation_logs).with(op)
|
422
|
-
|
423
|
-
subject.options = { size: 40 }
|
424
|
-
subject.send('db:restart', handle)
|
425
|
-
|
426
|
-
expect(captured_logs).to match(/restarting foobar/i)
|
427
|
-
end
|
428
|
-
|
429
407
|
it 'allows restarting a database with a disk-size' do
|
430
408
|
expect(database).to receive(:create_operation!)
|
431
409
|
.with(type: 'restart', disk_size: 40).and_return(op)
|
@@ -581,10 +559,6 @@ describe Aptible::CLI::Agent do
|
|
581
559
|
expect_replicate_database(container_size: 40)
|
582
560
|
end
|
583
561
|
|
584
|
-
it 'allows replicating a database with an (implicitly) disk size option' do
|
585
|
-
expect_replicate_database(size: 40)
|
586
|
-
end
|
587
|
-
|
588
562
|
it 'allows replicating a database with a disk-size option' do
|
589
563
|
expect_replicate_database(disk_size: 40)
|
590
564
|
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Aptible::CLI::Agent do
|
4
|
+
let(:account) { Fabricate(:account) }
|
5
|
+
let!(:log_drain) do
|
6
|
+
Fabricate(:log_drain, handle: 'test', account: account)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:token) { double('token') }
|
10
|
+
before { allow(subject).to receive(:fetch_token).and_return(token) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
allow(Aptible::Api::Account).to receive(:all)
|
14
|
+
.with(token: token).and_return([account])
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#log_drain:list' do
|
18
|
+
it 'lists a log drains for an account' do
|
19
|
+
subject.send('log_drain:list')
|
20
|
+
|
21
|
+
out = "=== aptible\n" \
|
22
|
+
"test\n"
|
23
|
+
expect(captured_output_text).to eq(out)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'lists log drains across multiple accounts' do
|
27
|
+
other_account = Fabricate(:account)
|
28
|
+
Fabricate(:log_drain, handle: 'test2', account: other_account)
|
29
|
+
accounts = [account, other_account]
|
30
|
+
allow(Aptible::Api::Account).to receive(:all).and_return(accounts)
|
31
|
+
|
32
|
+
subject.send('log_drain:list')
|
33
|
+
|
34
|
+
out = "=== aptible\n" \
|
35
|
+
"test\n" \
|
36
|
+
"test2\n"
|
37
|
+
expect(captured_output_text).to eq(out)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'lists log drains for a single account when --environment is included' do
|
41
|
+
other_account = Fabricate(:account)
|
42
|
+
Fabricate(:log_drain, handle: 'test2', account: other_account)
|
43
|
+
accounts = [account, other_account]
|
44
|
+
allow(Aptible::Api::Account).to receive(:all).and_return(accounts)
|
45
|
+
|
46
|
+
subject.options = { environment: account.handle }
|
47
|
+
subject.send('log_drain:list')
|
48
|
+
|
49
|
+
out = "=== aptible\n" \
|
50
|
+
"test\n"
|
51
|
+
expect(captured_output_text).to eq(out)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#log_drain:create' do
|
56
|
+
def expect_provision_log_drain(create_opts, provision_opts = {})
|
57
|
+
log_drain = Fabricate(:log_drain, account: account)
|
58
|
+
op = Fabricate(:operation)
|
59
|
+
|
60
|
+
expect(account).to receive(:create_log_drain!)
|
61
|
+
.with(**create_opts).and_return(log_drain)
|
62
|
+
|
63
|
+
expect(log_drain).to receive(:create_operation)
|
64
|
+
.with(type: :provision, **provision_opts).and_return(op)
|
65
|
+
|
66
|
+
expect(subject).to receive(:attach_to_operation_logs).with(op)
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'elasticsearch' do
|
70
|
+
let(:db) { Fabricate(:database, account: account, id: 5) }
|
71
|
+
|
72
|
+
it 'creates a new Elasticsearch log drain' do
|
73
|
+
opts = {
|
74
|
+
handle: 'test',
|
75
|
+
drain_apps: nil,
|
76
|
+
drain_databases: nil,
|
77
|
+
drain_ephemeral_sessions: nil,
|
78
|
+
drain_proxies: nil,
|
79
|
+
drain_type: :elasticsearch_database,
|
80
|
+
logging_token: nil,
|
81
|
+
database_id: db.id
|
82
|
+
}
|
83
|
+
expect_provision_log_drain(opts)
|
84
|
+
|
85
|
+
subject.options = {
|
86
|
+
db: db.handle,
|
87
|
+
environment: account.handle
|
88
|
+
}
|
89
|
+
subject.send('log_drain:create:elasticsearch', 'test')
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'creates a new Elasticsearch log drain with a pipeline' do
|
93
|
+
opts = {
|
94
|
+
handle: 'test-es',
|
95
|
+
drain_apps: nil,
|
96
|
+
drain_databases: nil,
|
97
|
+
drain_ephemeral_sessions: nil,
|
98
|
+
drain_proxies: nil,
|
99
|
+
drain_type: :elasticsearch_database,
|
100
|
+
logging_token: 'test-pipeline',
|
101
|
+
database_id: db.id
|
102
|
+
}
|
103
|
+
expect_provision_log_drain(opts)
|
104
|
+
|
105
|
+
subject.options = {
|
106
|
+
db: db.handle,
|
107
|
+
environment: account.handle,
|
108
|
+
pipeline: 'test-pipeline'
|
109
|
+
}
|
110
|
+
subject.send('log_drain:create:elasticsearch', 'test-es')
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# HTTPS, Datadog, Sumologic, and LogDNA are all similar enough
|
115
|
+
# that they're not tested individually
|
116
|
+
context 'https' do
|
117
|
+
it 'creates a new HTTPS log drain' do
|
118
|
+
opts = {
|
119
|
+
handle: 'test-https',
|
120
|
+
drain_apps: nil,
|
121
|
+
drain_databases: nil,
|
122
|
+
drain_ephemeral_sessions: nil,
|
123
|
+
drain_proxies: nil,
|
124
|
+
drain_type: :https_post,
|
125
|
+
url: 'https://test.foo.com'
|
126
|
+
}
|
127
|
+
expect_provision_log_drain(opts)
|
128
|
+
|
129
|
+
subject.options = {
|
130
|
+
environment: account.handle,
|
131
|
+
url: 'https://test.foo.com'
|
132
|
+
}
|
133
|
+
subject.send('log_drain:create:https', 'test-https')
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Syslog and Papertrail are similar enough that they're
|
138
|
+
# not tested individually
|
139
|
+
context 'syslog' do
|
140
|
+
it 'creates a new syslog log drain' do
|
141
|
+
opts = {
|
142
|
+
handle: 'test-syslog',
|
143
|
+
drain_host: 'test.foo.com',
|
144
|
+
drain_port: 2468,
|
145
|
+
logging_token: nil,
|
146
|
+
drain_apps: nil,
|
147
|
+
drain_databases: nil,
|
148
|
+
drain_ephemeral_sessions: nil,
|
149
|
+
drain_proxies: nil,
|
150
|
+
drain_type: :syslog_tls_tcp
|
151
|
+
}
|
152
|
+
expect_provision_log_drain(opts)
|
153
|
+
|
154
|
+
subject.options = {
|
155
|
+
environment: account.handle,
|
156
|
+
host: 'test.foo.com',
|
157
|
+
port: 2468
|
158
|
+
}
|
159
|
+
subject.send('log_drain:create:syslog', 'test-syslog')
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'creates a new syslog log drain with a logging token' do
|
163
|
+
opts = {
|
164
|
+
handle: 'test-syslog',
|
165
|
+
drain_host: 'test.foo.com',
|
166
|
+
drain_port: 2468,
|
167
|
+
logging_token: 'test-token',
|
168
|
+
drain_apps: nil,
|
169
|
+
drain_databases: nil,
|
170
|
+
drain_ephemeral_sessions: nil,
|
171
|
+
drain_proxies: nil,
|
172
|
+
drain_type: :syslog_tls_tcp
|
173
|
+
}
|
174
|
+
expect_provision_log_drain(opts)
|
175
|
+
|
176
|
+
subject.options = {
|
177
|
+
environment: account.handle,
|
178
|
+
host: 'test.foo.com',
|
179
|
+
port: 2468,
|
180
|
+
token: 'test-token'
|
181
|
+
}
|
182
|
+
subject.send('log_drain:create:syslog', 'test-syslog')
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe '#log_drain:deprovision' do
|
188
|
+
let(:operation) { Fabricate(:operation, resource: log_drain) }
|
189
|
+
|
190
|
+
it 'deprovisions a log drain' do
|
191
|
+
expect(log_drain).to receive(:create_operation)
|
192
|
+
.with(type: :deprovision).and_return(operation)
|
193
|
+
expect(subject).to receive(:attach_to_operation_logs).with(operation)
|
194
|
+
subject.send('log_drain:deprovision', log_drain.handle)
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'does not fail if the operation cannot be found' do
|
198
|
+
expect(log_drain).to receive(:create_operation)
|
199
|
+
.with(type: :deprovision).and_return(operation)
|
200
|
+
response = Faraday::Response.new(status: 404)
|
201
|
+
error = HyperResource::ClientError.new('Not Found', response: response)
|
202
|
+
expect(subject).to receive(:attach_to_operation_logs).with(operation)
|
203
|
+
.and_raise(error)
|
204
|
+
subject.send('log_drain:deprovision', log_drain.handle)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Aptible::CLI::Agent do
|
4
|
+
let(:account) { Fabricate(:account) }
|
5
|
+
let!(:metric_drain) do
|
6
|
+
Fabricate(:metric_drain, handle: 'test', account: account)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:token) { double('token') }
|
10
|
+
before { allow(subject).to receive(:fetch_token).and_return(token) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
allow(Aptible::Api::Account).to receive(:all)
|
14
|
+
.with(token: token).and_return([account])
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#metric_drain:list' do
|
18
|
+
it 'lists a metric drains for an account' do
|
19
|
+
subject.send('metric_drain:list')
|
20
|
+
|
21
|
+
out = "=== aptible\n" \
|
22
|
+
"test\n"
|
23
|
+
expect(captured_output_text).to eq(out)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'lists metric drains across multiple accounts' do
|
27
|
+
other_account = Fabricate(:account)
|
28
|
+
Fabricate(:metric_drain, handle: 'test2', account: other_account)
|
29
|
+
accounts = [account, other_account]
|
30
|
+
allow(Aptible::Api::Account).to receive(:all).and_return(accounts)
|
31
|
+
|
32
|
+
subject.send('metric_drain:list')
|
33
|
+
|
34
|
+
out = "=== aptible\n" \
|
35
|
+
"test\n" \
|
36
|
+
"test2\n"
|
37
|
+
expect(captured_output_text).to eq(out)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'lists metric drains for a single account with --environment' do
|
41
|
+
other_account = Fabricate(:account)
|
42
|
+
Fabricate(:metric_drain, handle: 'test2', account: other_account)
|
43
|
+
accounts = [account, other_account]
|
44
|
+
allow(Aptible::Api::Account).to receive(:all).and_return(accounts)
|
45
|
+
|
46
|
+
subject.options = { environment: account.handle }
|
47
|
+
subject.send('metric_drain:list')
|
48
|
+
|
49
|
+
out = "=== aptible\n" \
|
50
|
+
"test\n"
|
51
|
+
expect(captured_output_text).to eq(out)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#metric_drain:create' do
|
56
|
+
def expect_provision_metric_drain(create_opts, provision_opts = {})
|
57
|
+
metric_drain = Fabricate(:metric_drain, account: account)
|
58
|
+
op = Fabricate(:operation)
|
59
|
+
|
60
|
+
expect(account).to receive(:create_metric_drain!)
|
61
|
+
.with(**create_opts).and_return(metric_drain)
|
62
|
+
|
63
|
+
expect(metric_drain).to receive(:create_operation)
|
64
|
+
.with(type: :provision, **provision_opts).and_return(op)
|
65
|
+
|
66
|
+
expect(subject).to receive(:attach_to_operation_logs).with(op)
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'influxdb' do
|
70
|
+
let(:db) { Fabricate(:database, account: account, id: 5) }
|
71
|
+
|
72
|
+
it 'creates a new InfluxDB metric drain' do
|
73
|
+
opts = {
|
74
|
+
handle: 'test-influxdb',
|
75
|
+
drain_type: :influxdb_database,
|
76
|
+
database_id: db.id
|
77
|
+
}
|
78
|
+
expect_provision_metric_drain(opts)
|
79
|
+
|
80
|
+
subject.options = {
|
81
|
+
db: db.handle,
|
82
|
+
environment: account.handle
|
83
|
+
}
|
84
|
+
subject.send('metric_drain:create:influxdb', 'test-influxdb')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'influxdb:custom' do
|
89
|
+
it 'creates a new InfluxDB metric drain' do
|
90
|
+
opts = {
|
91
|
+
handle: 'test-influxdb-custom',
|
92
|
+
drain_type: :influxdb,
|
93
|
+
drain_configuration: {
|
94
|
+
address: 'https://test.foo.com:443',
|
95
|
+
database: 'foobar',
|
96
|
+
password: 'bar',
|
97
|
+
username: 'foo'
|
98
|
+
}
|
99
|
+
}
|
100
|
+
expect_provision_metric_drain(opts)
|
101
|
+
|
102
|
+
subject.options = {
|
103
|
+
environment: account.handle,
|
104
|
+
username: 'foo',
|
105
|
+
password: 'bar',
|
106
|
+
db: 'foobar',
|
107
|
+
url: 'https://test.foo.com:443'
|
108
|
+
}
|
109
|
+
subject.send('metric_drain:create:influxdb:custom',
|
110
|
+
'test-influxdb-custom')
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'datadog' do
|
115
|
+
it 'creates a new Datadog metric drain' do
|
116
|
+
opts = {
|
117
|
+
handle: 'test-datadog',
|
118
|
+
drain_type: :datadog,
|
119
|
+
drain_configuration: {
|
120
|
+
api_key: 'foobar'
|
121
|
+
}
|
122
|
+
}
|
123
|
+
expect_provision_metric_drain(opts)
|
124
|
+
|
125
|
+
subject.options = {
|
126
|
+
environment: account.handle,
|
127
|
+
api_key: 'foobar'
|
128
|
+
}
|
129
|
+
subject.send('metric_drain:create:datadog', 'test-datadog')
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'raises an error when the Datadog site is invalid' do
|
133
|
+
subject.options = {
|
134
|
+
environment: account.handle,
|
135
|
+
api_key: 'foobar',
|
136
|
+
site: 'BAD'
|
137
|
+
}
|
138
|
+
expect { subject.send('metric_drain:create:datadog', 'test-datadog') }
|
139
|
+
.to raise_error(Thor::Error, /Invalid Datadog site/i)
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'creates a new Datadog metric drain with a Datadog site defined' do
|
143
|
+
opts = {
|
144
|
+
handle: 'test-datadog',
|
145
|
+
drain_type: :datadog,
|
146
|
+
drain_configuration: {
|
147
|
+
api_key: 'foobar',
|
148
|
+
series_url: 'https://app.datadoghq.eu'
|
149
|
+
}
|
150
|
+
}
|
151
|
+
expect_provision_metric_drain(opts)
|
152
|
+
|
153
|
+
subject.options = {
|
154
|
+
environment: account.handle,
|
155
|
+
api_key: 'foobar',
|
156
|
+
site: 'EU1'
|
157
|
+
}
|
158
|
+
subject.send('metric_drain:create:datadog', 'test-datadog')
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe '#metric_drain:deprovision' do
|
164
|
+
let(:operation) { Fabricate(:operation, resource: metric_drain) }
|
165
|
+
|
166
|
+
it 'deprovisions a log drain' do
|
167
|
+
expect(metric_drain).to receive(:create_operation)
|
168
|
+
.with(type: :deprovision).and_return(operation)
|
169
|
+
expect(subject).to receive(:attach_to_operation_logs).with(operation)
|
170
|
+
subject.send('metric_drain:deprovision', metric_drain.handle)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'does not fail if the operation cannot be found' do
|
174
|
+
expect(metric_drain).to receive(:create_operation)
|
175
|
+
.with(type: :deprovision).and_return(operation)
|
176
|
+
response = Faraday::Response.new(status: 404)
|
177
|
+
error = HyperResource::ClientError.new('Not Found', response: response)
|
178
|
+
expect(subject).to receive(:attach_to_operation_logs).with(operation)
|
179
|
+
.and_raise(error)
|
180
|
+
subject.send('metric_drain:deprovision', metric_drain.handle)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|