aptible-cli 0.19.9 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32982651526f1859445bcdfa762881e25f68b72dbce3ecca1a0169a900f4cca5
4
- data.tar.gz: 21a14594b144844b6e833ba2f5811736d0c642839375aadbbea356853478c8ec
3
+ metadata.gz: b212760948b9bef6355281c713ae9077b7e424e21f5cdf4c5c88f60deb13b38d
4
+ data.tar.gz: 5dbf4dab98017d0a0c2a6201b4c7715cda3f46cbb481d64ba9ce7b5bf1fad2fc
5
5
  SHA512:
6
- metadata.gz: 50a22a2a0c8eee1b4c65912a0e986cb723250b7541a6ded2e31112ae11d06cca48ae05329395d1d8f44704e917818d037f3b5d47eac74f3f320ab39ed1496527
7
- data.tar.gz: 398cc5e09a3c0b1458a633ad4e5b0bcdb09040160207052face94142dee4b171ecfbe9c68af51007cb8e16cff03249e7821cd041834c4a161e66a10e770d0ea5
6
+ metadata.gz: 42335afa7c7bc447a120cbfcd7244ce326476d001922cb8eafcecd3c278a65859cb06d61234fc8607ab4cf9b7d31bf15dd60348ca2bc7af926e62def427386fa
7
+ data.tar.gz: 3e3dbe977c93e72a6cb621e3d6d529812ce9a2725ca6a309efce5f524acf93922259bb7814cd4958b63a168ce03e8184249e0fe8af061d3710e5fdb023e48299
data/.dockerignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ *.dump
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ /.idea
19
+ /.vscode
20
+ Makefile
data/.gitignore CHANGED
@@ -4,7 +4,6 @@
4
4
  .bundle
5
5
  .config
6
6
  .yardoc
7
- Gemfile.lock
8
7
  InstalledFiles
9
8
  _yardoc
10
9
  coverage
data/.travis.yml CHANGED
@@ -11,9 +11,10 @@ rvm:
11
11
  - "2.7"
12
12
 
13
13
  before_install:
14
- - ./cleanup_bundler
15
14
  - gem install bundler -v '< 2'
16
15
  script:
17
16
  - bundle exec rake
18
17
  - bundle exec script/sync-readme-usage
19
18
  - git diff --exit-code
19
+ env:
20
+ - BUNDLER_VERSION=1.17.3
data/Dockerfile CHANGED
@@ -1,10 +1,27 @@
1
1
  FROM ruby:2.7.8
2
2
 
3
+ # Install and use an compatible bundler
4
+ ENV BUNDLER_VERSION=1.17.3
5
+ RUN gem install bundler -v "${BUNDLER_VERSION}"
6
+
7
+ # Install required gems before copying in code
8
+ # to avoid re-installing gems when developing
3
9
  WORKDIR /app
4
- COPY . /app
10
+ COPY Gemfile /app
11
+ COPY Gemfile.lock /app
12
+ COPY aptible-cli.gemspec /app
13
+
14
+ # We reference the version, so copy that in, too
15
+ CMD mkdir -p /app/lib/aptible/cli/
16
+ COPY lib/aptible/cli/version.rb /app/lib/aptible/cli/
5
17
 
6
- RUN ./cleanup_bundler
7
- RUN gem install bundler -v '< 2'
8
18
  RUN bundle install
9
19
 
10
- CMD ["/app/bin/aptible"]
20
+ COPY . /app
21
+
22
+ # Save on typing while testing
23
+ RUN echo '#!/bin/bash' > /usr/bin/aptible \
24
+ && echo 'bundle exec bin/aptible $@' >> /usr/bin/aptible \
25
+ && chmod +x /usr/bin/aptible
26
+
27
+ CMD ["aptible"]
data/Gemfile.lock ADDED
@@ -0,0 +1,184 @@
1
+ GIT
2
+ remote: https://github.com/fancyremarker/pry.git
3
+ revision: be3823aa4ffc51260f2f3ce84f0984da3dc6dd10
4
+ branch: aptible
5
+ specs:
6
+ pry (0.10.0)
7
+ coderay (~> 1.1.0)
8
+ method_source (~> 0.8.1)
9
+ slop (~> 3.4)
10
+
11
+ PATH
12
+ remote: .
13
+ specs:
14
+ aptible-cli (0.21.0)
15
+ activesupport (>= 4.0, < 6.0)
16
+ aptible-api (~> 1.5.3)
17
+ aptible-auth (~> 1.2.4)
18
+ aptible-billing (~> 1.0)
19
+ aptible-resource (~> 1.1)
20
+ aws-sdk (~> 2.0)
21
+ bigdecimal (~> 1.3.5)
22
+ cbor
23
+ chronic_duration (~> 0.10.6)
24
+ git (< 1.10)
25
+ term-ansicolor
26
+ thor (~> 0.20.0)
27
+
28
+ GEM
29
+ remote: https://rubygems.org/
30
+ specs:
31
+ activesupport (4.2.11.3)
32
+ i18n (~> 0.7)
33
+ minitest (~> 5.1)
34
+ thread_safe (~> 0.3, >= 0.3.4)
35
+ tzinfo (~> 1.1)
36
+ addressable (2.8.0)
37
+ public_suffix (>= 2.0.2, < 5.0)
38
+ aptible-api (1.5.3)
39
+ aptible-auth (~> 1.0)
40
+ aptible-resource (~> 1.0)
41
+ gem_config
42
+ multipart-post (< 2.2.0)
43
+ aptible-auth (1.2.5)
44
+ aptible-resource (~> 1.0)
45
+ gem_config
46
+ multipart-post (= 2.1.1)
47
+ oauth2 (= 1.4.7)
48
+ aptible-billing (1.0.1)
49
+ activesupport (>= 4.0, < 6.0)
50
+ aptible-resource (~> 1.0)
51
+ stripe (>= 1.13.0)
52
+ aptible-resource (1.1.2)
53
+ activesupport
54
+ fridge
55
+ gem_config (~> 0.3.1)
56
+ httpclient (~> 2.8)
57
+ json
58
+ uri_template (>= 0.5.2)
59
+ aptible-tasks (0.5.9)
60
+ rake (>= 10, < 13.0)
61
+ rubocop (= 0.42.0)
62
+ ast (2.4.2)
63
+ aws-eventstream (1.1.1)
64
+ aws-sdk (2.11.632)
65
+ aws-sdk-resources (= 2.11.632)
66
+ aws-sdk-core (2.11.632)
67
+ aws-sigv4 (~> 1.0)
68
+ jmespath (~> 1.0)
69
+ aws-sdk-resources (2.11.632)
70
+ aws-sdk-core (= 2.11.632)
71
+ aws-sigv4 (1.2.4)
72
+ aws-eventstream (~> 1, >= 1.0.2)
73
+ bigdecimal (1.3.5)
74
+ cbor (0.5.9.8)
75
+ chronic_duration (0.10.6)
76
+ numerizer (~> 0.1.1)
77
+ climate_control (0.0.3)
78
+ activesupport (>= 3.0)
79
+ coderay (1.1.3)
80
+ concurrent-ruby (1.1.9)
81
+ connection_pool (2.2.3)
82
+ crack (1.0.0)
83
+ bigdecimal
84
+ rexml
85
+ diff-lcs (1.5.1)
86
+ fabrication (2.15.2)
87
+ faraday (0.17.6)
88
+ multipart-post (>= 1.2, < 3)
89
+ fridge (0.2.2)
90
+ gem_config
91
+ jwt
92
+ gem_config (0.3.2)
93
+ git (1.7.0)
94
+ rchardet (~> 1.8)
95
+ hashdiff (1.1.0)
96
+ httpclient (2.8.3)
97
+ i18n (0.9.5)
98
+ concurrent-ruby (~> 1.0)
99
+ jmespath (1.6.2)
100
+ json (2.5.1)
101
+ jwt (2.3.0)
102
+ method_source (0.8.2)
103
+ minitest (5.12.0)
104
+ multi_json (1.15.0)
105
+ multi_xml (0.6.0)
106
+ multipart-post (2.1.1)
107
+ net-http-persistent (3.1.0)
108
+ connection_pool (~> 2.2)
109
+ numerizer (0.1.1)
110
+ oauth2 (1.4.7)
111
+ faraday (>= 0.8, < 2.0)
112
+ jwt (>= 1.0, < 3.0)
113
+ multi_json (~> 1.3)
114
+ multi_xml (~> 0.5)
115
+ rack (>= 1.2, < 3)
116
+ parser (2.7.2.0)
117
+ ast (~> 2.4.1)
118
+ powerpack (0.1.3)
119
+ public_suffix (3.1.1)
120
+ rack (1.6.13)
121
+ rainbow (2.2.2)
122
+ rake
123
+ rake (12.3.3)
124
+ rchardet (1.8.0)
125
+ rexml (3.2.5)
126
+ rspec (3.13.0)
127
+ rspec-core (~> 3.13.0)
128
+ rspec-expectations (~> 3.13.0)
129
+ rspec-mocks (~> 3.13.0)
130
+ rspec-core (3.13.0)
131
+ rspec-support (~> 3.13.0)
132
+ rspec-expectations (3.13.0)
133
+ diff-lcs (>= 1.2.0, < 2.0)
134
+ rspec-support (~> 3.13.0)
135
+ rspec-mocks (3.13.1)
136
+ diff-lcs (>= 1.2.0, < 2.0)
137
+ rspec-support (~> 3.13.0)
138
+ rspec-support (3.13.1)
139
+ rubocop (0.42.0)
140
+ parser (>= 2.3.1.1, < 3.0)
141
+ powerpack (~> 0.1)
142
+ rainbow (>= 1.99.1, < 3.0)
143
+ ruby-progressbar (~> 1.7)
144
+ unicode-display_width (~> 1.0, >= 1.0.1)
145
+ ruby-progressbar (1.13.0)
146
+ slop (3.6.0)
147
+ stripe (4.24.0)
148
+ faraday (~> 0.13)
149
+ net-http-persistent (~> 3.0)
150
+ sync (0.5.0)
151
+ term-ansicolor (1.8.0)
152
+ tins (~> 1.0)
153
+ thor (0.20.3)
154
+ thread_safe (0.3.6)
155
+ tins (1.33.0)
156
+ bigdecimal
157
+ sync
158
+ tzinfo (1.2.11)
159
+ thread_safe (~> 0.1)
160
+ unicode-display_width (1.8.0)
161
+ uri_template (0.7.0)
162
+ webmock (3.16.2)
163
+ addressable (>= 2.8.0)
164
+ crack (>= 0.3.2)
165
+ hashdiff (>= 0.4.0, < 2.0.0)
166
+
167
+ PLATFORMS
168
+ ruby
169
+
170
+ DEPENDENCIES
171
+ activesupport (~> 4.0)
172
+ aptible-cli!
173
+ aptible-tasks (~> 0.5.8)
174
+ bundler (~> 1.3)
175
+ climate_control (= 0.0.3)
176
+ fabrication (~> 2.15.2)
177
+ pry!
178
+ rack (~> 1.0)
179
+ rake
180
+ rspec (~> 3.2)
181
+ webmock
182
+
183
+ BUNDLED WITH
184
+ 1.17.3
data/Makefile ADDED
@@ -0,0 +1,10 @@
1
+ build:
2
+ docker compose build --pull
3
+
4
+ bash: build
5
+ docker compose run cli bash
6
+
7
+ test: build
8
+ docker compose run cli bundle exec rake
9
+
10
+ .PHONY: build bash test
data/README.md CHANGED
@@ -30,13 +30,13 @@ Commands:
30
30
  aptible apps:create HANDLE # Create a new application
31
31
  aptible apps:deprovision # Deprovision an app
32
32
  aptible apps:rename OLD_HANDLE NEW_HANDLE [--environment ENVIRONMENT_HANDLE] # Rename an app handle. In order for the new app handle to appear in log drain and metric drain destinations, you must restart the app.
33
- aptible apps:scale SERVICE [--container-count COUNT] [--container-size SIZE_MB] # Scale a service
33
+ aptible apps:scale SERVICE [--container-count COUNT] [--container-size SIZE_MB] [--container-profile PROFILE] # Scale a service
34
34
  aptible backup:list DB_HANDLE # List backups for a database
35
35
  aptible backup:orphaned # List backups associated with deprovisioned databases
36
36
  aptible backup:purge BACKUP_ID # Permanently delete a backup and any copies of it
37
- aptible backup:restore BACKUP_ID [--environment ENVIRONMENT_HANDLE] [--handle HANDLE] [--container-size SIZE_MB] [--disk-size SIZE_GB] [--key-arn KEY_ARN] # Restore a backup
37
+ aptible backup:restore BACKUP_ID [--environment ENVIRONMENT_HANDLE] [--handle HANDLE] [--container-size SIZE_MB] [--disk-size SIZE_GB] [--container-profile PROFILE] [--iops IOPS] [--key-arn KEY_ARN] # Restore a backup
38
38
  aptible backup_retention_policy [ENVIRONMENT_HANDLE] # Show the current backup retention policy for the environment
39
- aptible backup_retention_policy:set [ENVIRONMENT_HANDLE] [--daily DAILY_BACKUPS] [--monthly MONTHLY_BACKUPS] [--yearly YEARLY_BACKUPS] [--make-copy|--no-make-copy] [--keep-final|--no-keep-final] # Set the environemnt's backup retention policy
39
+ aptible backup_retention_policy:set [ENVIRONMENT_HANDLE] [--daily DAILY_BACKUPS] [--monthly MONTHLY_BACKUPS] [--yearly YEARLY_BACKUPS] [--make-copy|--no-make-copy] [--keep-final|--no-keep-final] [--force] # Change the environment's backup retention policy
40
40
  aptible config # Print an app's current configuration
41
41
  aptible config:add [VAR1=VAL1] [VAR2=VAL2] [...] # Add an ENV variable to an app
42
42
  aptible config:get [VAR1] # Print a specific key within an app's current configuration
@@ -45,7 +45,7 @@ Commands:
45
45
  aptible config:unset [VAR1] [VAR2] [...] # Remove an ENV variable from an app
46
46
  aptible db:backup HANDLE # Backup a database
47
47
  aptible db:clone SOURCE DEST # Clone a database to create a new one
48
- aptible db:create HANDLE [--type TYPE] [--version VERSION] [--container-size SIZE_MB] [--disk-size SIZE_GB] [--key-arn KEY_ARN] # Create a new database
48
+ aptible db:create HANDLE [--type TYPE] [--version VERSION] [--container-size SIZE_MB] [--disk-size SIZE_GB] [--container-profile PROFILE] [--iops IOPS] [--key-arn KEY_ARN] # Create a new database
49
49
  aptible db:deprovision HANDLE # Deprovision a database
50
50
  aptible db:dump HANDLE [pg_dump options] # Dump a remote database to file
51
51
  aptible db:execute HANDLE SQL_FILE [--on-error-stop] # Executes sql against a database
@@ -53,8 +53,8 @@ Commands:
53
53
  aptible db:modify HANDLE [--iops IOPS] [--volume-type [gp2, gp3]] # Modify a database disk
54
54
  aptible db:reload HANDLE # Reload a database
55
55
  aptible db:rename OLD_HANDLE NEW_HANDLE [--environment ENVIRONMENT_HANDLE] # Rename a database handle. In order for the new database handle to appear in log drain and metric drain destinations, you must reload the database.
56
- aptible db:replicate HANDLE REPLICA_HANDLE [--container-size SIZE_MB] [--disk-size SIZE_GB] [--logical --version VERSION] [--key-arn KEY_ARN] # Create a replica/follower of a database
57
- aptible db:restart HANDLE [--container-size SIZE_MB] [--disk-size SIZE_GB] [--iops IOPS] [--volume-type [gp2, gp3]] # Restart a database
56
+ aptible db:replicate HANDLE REPLICA_HANDLE [--container-size SIZE_MB] [--disk-size SIZE_GB] [--container-profile PROFILE] [--iops IOPS] [--logical --version VERSION] [--key-arn KEY_ARN] # Create a replica/follower of a database
57
+ aptible db:restart HANDLE [--container-size SIZE_MB] [--disk-size SIZE_GB] [--container-profile PROFILE] [--iops IOPS] [--volume-type [gp2, gp3]] # Restart a database
58
58
  aptible db:tunnel HANDLE # Create a local tunnel to a database
59
59
  aptible db:url HANDLE # Display a database URL
60
60
  aptible db:versions # List available database versions
data/aptible-cli.gemspec CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ['lib']
22
22
 
23
23
  spec.add_dependency 'aptible-resource', '~> 1.1'
24
- spec.add_dependency 'aptible-api', '~> 1.4'
24
+ spec.add_dependency 'aptible-api', '~> 1.5.3'
25
25
  spec.add_dependency 'aptible-auth', '~> 1.2.4'
26
26
  spec.add_dependency 'aptible-billing', '~> 1.0'
27
27
  spec.add_dependency 'thor', '~> 0.20.0'
data/docker-compose.yml CHANGED
@@ -1,10 +1,10 @@
1
1
  services:
2
- # docker compose run cli bash
3
- # export APTIBLE_ACCESS_TOKEN=xxx
4
- # bundle exec ./bin/aptible help
5
2
  cli:
6
3
  build: .
7
4
  volumes:
8
5
  - type: bind
9
6
  source: .
10
7
  target: /app
8
+ - type: bind
9
+ source: $HOME/.aptible/tokens.json
10
+ target: /root/.aptible/tokens.json
@@ -52,7 +52,9 @@ module Aptible
52
52
  handle: dest_handle,
53
53
  container_size: options[:container_size],
54
54
  disk_size: options[:size],
55
- key_arn: options[:key_arn]
55
+ key_arn: options[:key_arn],
56
+ instance_profile: options[:instance_profile],
57
+ provisioned_iops: options[:provisioned_iops]
56
58
  }.reject { |_, v| v.nil? }
57
59
 
58
60
  if options[:logical]
@@ -47,16 +47,20 @@ module Aptible
47
47
  end
48
48
 
49
49
  desc 'apps:scale SERVICE ' \
50
- '[--container-count COUNT] [--container-size SIZE_MB]',
50
+ '[--container-count COUNT] [--container-size SIZE_MB] ' \
51
+ '[--container-profile PROFILE]',
51
52
  'Scale a service'
52
53
  app_options
53
54
  option :container_count, type: :numeric
54
55
  option :container_size, type: :numeric
56
+ option :container_profile, type: :string,
57
+ desc: 'Examples: m c r'
55
58
  define_method 'apps:scale' do |type|
56
59
  service = ensure_service(options, type)
57
60
 
58
61
  container_count = options[:container_count]
59
62
  container_size = options[:container_size]
63
+ container_profile = options[:container_profile]
60
64
 
61
65
  if options[:size]
62
66
  m = 'You have used the "--size" option to specify a container '\
@@ -74,6 +78,7 @@ module Aptible
74
78
  opts = { type: 'scale' }
75
79
  opts[:container_count] = container_count if container_count
76
80
  opts[:container_size] = container_size if container_size
81
+ opts[:instance_profile] = container_profile if container_profile
77
82
 
78
83
  op = service.create_operation!(opts)
79
84
  attach_to_operation_logs(op)
@@ -10,6 +10,7 @@ module Aptible
10
10
  desc 'backup:restore BACKUP_ID ' \
11
11
  '[--environment ENVIRONMENT_HANDLE] [--handle HANDLE] ' \
12
12
  '[--container-size SIZE_MB] [--disk-size SIZE_GB] ' \
13
+ '[--container-profile PROFILE] [--iops IOPS] ' \
13
14
  '[--key-arn KEY_ARN]',
14
15
  'Restore a backup'
15
16
  option :handle, desc: 'a name to use for the new database'
@@ -18,6 +19,9 @@ module Aptible
18
19
  option :size, type: :numeric
19
20
  option :disk_size, type: :numeric
20
21
  option :key_arn, type: :string
22
+ option :container_profile, type: :string,
23
+ desc: 'Examples: m c r'
24
+ option :iops, type: :numeric
21
25
  define_method 'backup:restore' do |backup_id|
22
26
  backup = Aptible::Api::Backup.find(backup_id, token: fetch_token)
23
27
  raise Thor::Error, "Backup ##{backup_id} not found" if backup.nil?
@@ -41,7 +45,9 @@ module Aptible
41
45
  container_size: options[:container_size],
42
46
  disk_size: options[:disk_size],
43
47
  destination_account: destination_account,
44
- key_arn: options[:key_arn]
48
+ key_arn: options[:key_arn],
49
+ instance_profile: options[:container_profile],
50
+ provisioned_iops: options[:iops]
45
51
  }.delete_if { |_, v| v.nil? }
46
52
 
47
53
  if options[:size]
@@ -17,14 +17,8 @@ module Aptible
17
17
  account = ensure_environment(environment: env)
18
18
  policy = account.backup_retention_policies.first
19
19
  unless policy
20
- # Show the default policy
21
- policy = Aptible::Api::BackupRetentionPolicy.new
22
- policy.attributes[:id] = 'default'
23
- policy.attributes[:daily] = 90
24
- policy.attributes[:monthly] = 72
25
- policy.attributes[:yearly] = 0
26
- policy.attributes[:make_copy] = true
27
- policy.attributes[:keep_final] = true
20
+ raise Thor::Error, "Environment #{env} does not have a " \
21
+ 'custom backup retention policy'
28
22
  end
29
23
 
30
24
  Formatter.render(Renderer.current) do |root|
@@ -39,35 +33,86 @@ module Aptible
39
33
  desc 'backup_retention_policy:set [ENVIRONMENT_HANDLE] ' \
40
34
  '[--daily DAILY_BACKUPS] [--monthly MONTHLY_BACKUPS] ' \
41
35
  '[--yearly YEARLY_BACKUPS] [--make-copy|--no-make-copy] ' \
42
- '[--keep-final|--no-keep-final]',
43
- "Set the environemnt's backup retention policy"
36
+ '[--keep-final|--no-keep-final] [--force]',
37
+ "Change the environment's backup retention policy"
44
38
  option :daily, type: :numeric,
45
- desc: 'Number of daily backups to retain',
46
- default: 90
39
+ desc: 'Number of daily backups to retain'
47
40
  option :monthly, type: :numeric,
48
- desc: 'Number of monthly backups to retain',
49
- default: 72
41
+ desc: 'Number of monthly backups to retain'
50
42
  option :yearly, type: :numeric,
51
- desc: 'Number of yarly backups to retain',
52
- default: 0
43
+ desc: 'Number of yearly backups to retain'
53
44
  option :make_copy, type: :boolean,
54
- desc: 'If backup copies should be created',
55
- default: true
56
- option(
57
- :keep_final,
58
- type: :boolean,
59
- desc: 'If final backups should be kept when databases are '\
60
- 'deprovisioned',
61
- default: true
62
- )
45
+ desc: 'If backup copies should be created'
46
+ option :keep_final,
47
+ type: :boolean,
48
+ desc: 'If final backups should be kept when databases are ' \
49
+ 'deprovisioned'
50
+ option :force,
51
+ type: :boolean,
52
+ desc: 'Do not prompt for confirmation if the new policy ' \
53
+ 'retains fewer backups than the current policy'
63
54
  define_method 'backup_retention_policy:set' do |env|
55
+ if options.empty?
56
+ raise Thor::Error,
57
+ 'Please specify at least one attribute to change'
58
+ end
59
+
64
60
  account = ensure_environment(environment: env)
65
- policy = account.create_backup_retention_policy!(**options)
61
+ current_policy = account.backup_retention_policies.first
62
+
63
+ # If an attribute isn't provided, use the value from the current
64
+ # policy
65
+ attrs = {}
66
+ %i(daily monthly yearly make_copy keep_final).each do |a|
67
+ opt = options[a]
68
+ attrs[a] = opt.nil? ? current_policy.try(a) : opt
69
+ end
70
+
71
+ # If any of the attribues are missing, raise an error so that
72
+ # we're not relying on the server's defaults
73
+ if attrs.values.any?(&:nil?)
74
+ raise Thor::Error, "Environment #{env} does not have a " \
75
+ 'custom backup retention policy. Please ' \
76
+ 'specify all attributes to create one.'
77
+ end
78
+
79
+ # Check if the number of backups over any period have been reduced
80
+ do_confirm = %i(daily monthly yearly).any? do |a|
81
+ cur = current_policy.try(a)
82
+ next if cur.nil?
83
+ cur > attrs[a]
84
+ end
85
+
86
+ # Check if any of the boolean fields have been disabled
87
+ do_confirm ||= %i(make_copy keep_final).any? do |a|
88
+ cur = current_policy.try(a)
89
+ next if cur.nil?
90
+ cur && !attrs[a]
91
+ end
92
+
93
+ if do_confirm && !options[:force]
94
+ m = 'The specified backup retention policy retains fewer ' \
95
+ "backups than the environment's current policy. This may " \
96
+ 'result in the deletion of existing, automated backups ' \
97
+ "if they exceed the new policy's rules and it may " \
98
+ "violate your company's internal compliance controls. " \
99
+ 'For more information, see https://www.aptible.com/docs' \
100
+ '/core-concepts/managed-databases/managing-databases' \
101
+ '/database-backups.'
102
+
103
+ m = set_color(m, :yellow)
104
+ print_wrapped m
105
+ confirmation = yes?('Do you want to proceed [y/N]:')
106
+ puts ''
107
+ raise Thor::Error, 'Aborting' unless confirmation
108
+ end
109
+
110
+ new_policy = account.create_backup_retention_policy!(**attrs)
66
111
 
67
112
  Formatter.render(Renderer.current) do |root|
68
113
  root.object do |node|
69
114
  ResourceFormatter.inject_backup_retention_policy(
70
- node, policy.reload, account
115
+ node, new_policy.reload, account
71
116
  )
72
117
  end
73
118
  end
@@ -54,6 +54,7 @@ module Aptible
54
54
  desc 'db:create HANDLE ' \
55
55
  '[--type TYPE] [--version VERSION] ' \
56
56
  '[--container-size SIZE_MB] [--disk-size SIZE_GB] ' \
57
+ '[--container-profile PROFILE] [--iops IOPS] ' \
57
58
  '[--key-arn KEY_ARN]',
58
59
  'Create a new database'
59
60
  option :type, type: :string
@@ -63,6 +64,9 @@ module Aptible
63
64
  option :size, type: :numeric
64
65
  option :key_arn, type: :string
65
66
  option :environment
67
+ option :container_profile, type: :string,
68
+ desc: 'Examples: m c r'
69
+ option :iops, type: :numeric
66
70
  define_method 'db:create' do |handle|
67
71
  account = ensure_environment(options)
68
72
 
@@ -100,8 +104,11 @@ module Aptible
100
104
  op_opts = {
101
105
  type: 'provision',
102
106
  container_size: options[:container_size],
103
- disk_size: options[:disk_size]
107
+ disk_size: options[:disk_size],
108
+ instance_profile: options[:container_profile],
109
+ provisioned_iops: options[:iops]
104
110
  }.delete_if { |_, v| v.nil? }
111
+
105
112
  op = database.create_operation(op_opts)
106
113
 
107
114
  if op.errors.any?
@@ -129,6 +136,7 @@ module Aptible
129
136
 
130
137
  desc 'db:replicate HANDLE REPLICA_HANDLE ' \
131
138
  '[--container-size SIZE_MB] [--disk-size SIZE_GB] ' \
139
+ '[--container-profile PROFILE] [--iops IOPS] ' \
132
140
  '[--logical --version VERSION] [--key-arn KEY_ARN]',
133
141
  'Create a replica/follower of a database'
134
142
  option :environment
@@ -138,6 +146,9 @@ module Aptible
138
146
  option :logical, type: :boolean
139
147
  option :version, type: :string
140
148
  option :key_arn, type: :string
149
+ option :container_profile, type: :string,
150
+ desc: 'Examples: m c r'
151
+ option :iops, type: :numeric
141
152
  define_method 'db:replicate' do |source_handle, dest_handle|
142
153
  source = ensure_database(options.merge(db: source_handle))
143
154
 
@@ -162,7 +173,9 @@ module Aptible
162
173
  size: options[:disk_size],
163
174
  logical: options[:logical],
164
175
  database_image: image || nil,
165
- key_arn: options[:key_arn]
176
+ key_arn: options[:key_arn],
177
+ instance_profile: options[:container_profile],
178
+ provisioned_iops: options[:iops]
166
179
  }.delete_if { |_, v| v.nil? }
167
180
 
168
181
  if options[:size]
@@ -284,10 +297,13 @@ module Aptible
284
297
 
285
298
  desc 'db:restart HANDLE ' \
286
299
  '[--container-size SIZE_MB] [--disk-size SIZE_GB] ' \
287
- '[--iops IOPS] [--volume-type [gp2, gp3]]',
300
+ '[--container-profile PROFILE] [--iops IOPS] ' \
301
+ '[--volume-type [gp2, gp3]]',
288
302
  'Restart a database'
289
303
  option :environment
290
304
  option :container_size, type: :numeric
305
+ option :container_profile, type: :string,
306
+ desc: 'Examples: m c r'
291
307
  option :disk_size, type: :numeric
292
308
  option :size, type: :numeric
293
309
  option :iops, type: :numeric
@@ -300,7 +316,8 @@ module Aptible
300
316
  container_size: options[:container_size],
301
317
  disk_size: options[:disk_size],
302
318
  provisioned_iops: options[:iops],
303
- ebs_volume_type: options[:volume_type]
319
+ ebs_volume_type: options[:volume_type],
320
+ instance_profile: options[:container_profile]
304
321
  }.delete_if { |_, v| v.nil? }
305
322
 
306
323
  if options[:size]
@@ -327,7 +344,8 @@ module Aptible
327
344
  opts = {
328
345
  type: 'modify',
329
346
  provisioned_iops: options[:iops],
330
- ebs_volume_type: options[:volume_type]
347
+ ebs_volume_type: options[:volume_type],
348
+ instance_profile: options[:container_profile]
331
349
  }.delete_if { |_, v| v.nil? }
332
350
 
333
351
  CLI.logger.info "Modifying #{database.handle}..."
@@ -29,6 +29,16 @@ module Aptible
29
29
  desc: 'Detach this app from its git repository: ' \
30
30
  'its Procfile, Dockerfile, and .aptible.yml will be ' \
31
31
  'ignored until you deploy again with git'
32
+ option :container_count, type: :numeric,
33
+ desc: 'This option only affects new ' \
34
+ 'services, not existing ones.'
35
+ option :container_size, type: :numeric,
36
+ desc: 'This option only affects new ' \
37
+ 'services, not existing ones.'
38
+ option :container_profile, type: :string,
39
+ desc: 'This option only affects new ' \
40
+ 'services, not existing ones. ' \
41
+ 'Examples: m c r'
32
42
  DOCKER_IMAGE_DEPLOY_ARGS.each_pair do |opt, var|
33
43
  option opt,
34
44
  type: :string, banner: var,
@@ -63,8 +73,11 @@ module Aptible
63
73
  opts = {
64
74
  type: 'deploy',
65
75
  env: env,
66
- git_ref: git_ref
67
- }.delete_if { |_, v| v.nil? || v.empty? }
76
+ git_ref: git_ref,
77
+ container_count: options[:container_count],
78
+ container_size: options[:container_size],
79
+ instance_profile: options[:container_profile]
80
+ }.delete_if { |_, v| v.nil? || v.try(:empty?) }
68
81
 
69
82
  allow_it = [
70
83
  opts[:git_ref],
@@ -175,7 +175,7 @@ module Aptible
175
175
 
176
176
  WARNING: review the documentation on rate limits before using
177
177
  this command automatically
178
- (http://go.aptible.com/managed-tls-rate-limits).
178
+ (https://www.aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/managed-tls#rate-limits).
179
179
  LONGDESC
180
180
  app_options
181
181
  define_method 'endpoints:renew' do |hostname|
@@ -1,5 +1,5 @@
1
1
  module Aptible
2
2
  module CLI
3
- VERSION = '0.19.9'.freeze
3
+ VERSION = '0.21.0'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ describe Aptible::CLI::Agent do
4
+ let(:token) { 'some-token' }
5
+ let(:account) { Fabricate(:account, handle: 'test') }
6
+ let(:database) { Fabricate(:database, account: account, handle: 'some-db') }
7
+ let!(:policy) do
8
+ # created_at: 2016-06-14 13:24:11 +0000
9
+ Fabricate(:backup_retention_policy, account: account)
10
+ end
11
+
12
+ let(:default_handle) { 'some-db-at-2016-06-14-13-24-11' }
13
+
14
+ before do
15
+ allow(subject).to receive(:fetch_token).and_return(token)
16
+ allow(Aptible::Api::Account).to receive(:all) { [account] }
17
+ end
18
+
19
+ describe '#backup_retention_policy' do
20
+ it 'raises an error if the environment has no policy' do
21
+ allow(account).to receive(:backup_retention_policies).and_return([])
22
+ expect { subject.backup_retention_policy('test') }
23
+ .to raise_error(/does not have a custom backup retention policy/)
24
+ end
25
+
26
+ it "prints the enviroment's current policy" do
27
+ subject.backup_retention_policy('test')
28
+ out = captured_output_text
29
+ expect(out).to match(/daily: 30/i)
30
+ expect(out).to match(/monthly: 12/i)
31
+ expect(out).to match(/yearly: 6/i)
32
+ expect(out).to match(/make copy: true/i)
33
+ expect(out).to match(/keep final: true/i)
34
+ expect(out).to match(/environment: test/i)
35
+ end
36
+ end
37
+
38
+ describe '#backup_retention_policy:set' do
39
+ it 'requires all attributes if the environment has no policy' do
40
+ allow(account).to receive(:backup_retention_policies).and_return([])
41
+ opts = {
42
+ daily: 3,
43
+ monthly: 2,
44
+ yearly: 1,
45
+ make_copy: false,
46
+ keep_final: true
47
+ }
48
+
49
+ opts.each_key do |k|
50
+ missing_opts = opts.clone
51
+ missing_opts.delete(k)
52
+
53
+ subject.options = missing_opts
54
+ expect { subject.send('backup_retention_policy:set', 'test') }
55
+ .to raise_error(/please specify all attributes/i)
56
+ end
57
+
58
+ expect(account).to receive(:create_backup_retention_policy!)
59
+ .with(**opts).and_return(Fabricate(:backup_retention_policy))
60
+ subject.options = opts
61
+ subject.send('backup_retention_policy:set', 'test')
62
+ end
63
+
64
+ it 'merges provided options with the current policy' do
65
+ expected_opts = {
66
+ daily: 5,
67
+ monthly: policy.monthly,
68
+ yearly: policy.yearly,
69
+ make_copy: policy.make_copy,
70
+ keep_final: false
71
+ }
72
+
73
+ expect(account).to receive(:create_backup_retention_policy!)
74
+ .with(**expected_opts).and_return(Fabricate(:backup_retention_policy))
75
+ subject.options = { daily: 5, keep_final: false, force: true }
76
+ subject.send('backup_retention_policy:set', 'test')
77
+ end
78
+
79
+ it 'prompts the user if the new policy retains fewer backups' do
80
+ subject.options = { daily: 0 }
81
+
82
+ # Reject Prompt
83
+ expect(subject).to receive(:yes?).with(/do you want to proceed/i)
84
+
85
+ expect { subject.send('backup_retention_policy:set', 'test') }
86
+ .to raise_error(/aborting/i)
87
+
88
+ # Accept Prompt
89
+ expect(subject).to receive(:yes?).with(/do you want to proceed/i)
90
+ .and_return(true)
91
+
92
+ expect(account).to receive(:create_backup_retention_policy!)
93
+ .and_return(Fabricate(:backup_retention_policy))
94
+
95
+ subject.send('backup_retention_policy:set', 'test')
96
+ end
97
+
98
+ it '--force skips the confirmation promt' do
99
+ subject.options = { make_copy: false }
100
+
101
+ # Reject Prompt
102
+ expect(subject).to receive(:yes?).with(/do you want to proceed/i)
103
+
104
+ expect { subject.send('backup_retention_policy:set', 'test') }
105
+ .to raise_error(/aborting/i)
106
+
107
+ # --force
108
+ subject.options[:force] = true
109
+ expect(account).to receive(:create_backup_retention_policy!)
110
+ .and_return(Fabricate(:backup_retention_policy))
111
+
112
+ subject.send('backup_retention_policy:set', 'test')
113
+ end
114
+ end
115
+ end
@@ -116,6 +116,21 @@ describe Aptible::CLI::Agent do
116
116
  subject.send('backup:restore', 1)
117
117
  end
118
118
 
119
+ it 'accept scaling options' do
120
+ expect(backup).to receive(:create_operation!) do |options|
121
+ expect(options[:instance_profile]).to eq('m5')
122
+ expect(options[:provisioned_iops]).to eq(4000)
123
+ op
124
+ end
125
+
126
+ expect(subject).to receive(:attach_to_operation_logs).with(op) do
127
+ Fabricate(:database, account: account, handle: default_handle)
128
+ end
129
+
130
+ subject.options = { container_profile: 'm5', iops: 4000 }
131
+ subject.send('backup:restore', 1)
132
+ end
133
+
119
134
  it 'accepts an destination environment' do
120
135
  expect(backup).to receive(:create_operation!) do |options|
121
136
  expect(options[:handle]).to be_present
@@ -70,6 +70,20 @@ describe Aptible::CLI::Agent do
70
70
  subject.send('db:create', 'foo')
71
71
  end
72
72
 
73
+ it 'creates a new DB with container profile and iops' do
74
+ expect_provision_database(
75
+ { handle: 'foo', type: 'postgresql' },
76
+ { instance_profile: 'm5', provisioned_iops: 4000 }
77
+ )
78
+
79
+ subject.options = {
80
+ type: 'postgresql',
81
+ container_profile: 'm5',
82
+ iops: 4000
83
+ }
84
+ subject.send('db:create', 'foo')
85
+ end
86
+
73
87
  it 'deprovisions the database if the operation cannot be created' do
74
88
  db = Fabricate(:database)
75
89
 
@@ -160,6 +160,27 @@ describe Aptible::CLI::Agent do
160
160
  expect { subject.deploy }
161
161
  .to raise_error(/either from git.*docker/im)
162
162
  end
163
+
164
+ it 'allows providing scaling options' do
165
+ stub_options(
166
+ container_profile: 'm5',
167
+ container_size: 1024,
168
+ container_count: 2
169
+ )
170
+
171
+ expect(app).to receive(:create_operation!)
172
+ .with(
173
+ type: 'deploy',
174
+ container_size: 1024,
175
+ instance_profile: 'm5',
176
+ container_count: 2
177
+ )
178
+ .and_return(operation)
179
+ expect(subject).to receive(:attach_to_operation_logs)
180
+ .with(operation)
181
+
182
+ subject.deploy
183
+ end
163
184
  end
164
185
  end
165
186
  end
@@ -28,5 +28,6 @@ Fabricator(:account, from: :stub_account) do
28
28
  certificates { [] }
29
29
  log_drains { [] }
30
30
  metric_drains { [] }
31
+ backup_retention_policies { [] }
31
32
  created_at { Time.now }
32
33
  end
@@ -0,0 +1,18 @@
1
+ class StubBackupRetentionPolicy < OpenStruct
2
+ def reload
3
+ self
4
+ end
5
+ end
6
+
7
+ Fabricator(:backup_retention_policy, from: :stub_backup_retention_policy) do
8
+ id { sequence(:backup_retention_policy_id) }
9
+ created_at { Time.now }
10
+ daily { 30 }
11
+ monthly { 12 }
12
+ yearly { 6 }
13
+ make_copy { true }
14
+ keep_final { true }
15
+ account
16
+
17
+ after_create { |policy| policy.account.backup_retention_policies << policy }
18
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aptible-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.9
4
+ version: 0.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank Macreery
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-29 00:00:00.000000000 Z
11
+ date: 2024-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aptible-resource
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.4'
33
+ version: 1.5.3
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.4'
40
+ version: 1.5.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: aptible-auth
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -290,20 +290,22 @@ executables:
290
290
  extensions: []
291
291
  extra_rdoc_files: []
292
292
  files:
293
+ - ".dockerignore"
293
294
  - ".github/CODEOWNERS"
294
295
  - ".gitignore"
295
296
  - ".rspec"
296
297
  - ".travis.yml"
297
298
  - Dockerfile
298
299
  - Gemfile
300
+ - Gemfile.lock
299
301
  - LICENSE.md
302
+ - Makefile
300
303
  - README.md
301
304
  - Rakefile
302
305
  - SECURITY.md
303
306
  - appveyor.yml
304
307
  - aptible-cli.gemspec
305
308
  - bin/aptible
306
- - cleanup_bundler
307
309
  - codecov.yml
308
310
  - docker-compose.yml
309
311
  - lib/aptible/cli.rb
@@ -377,6 +379,7 @@ files:
377
379
  - spec/aptible/cli/renderer/text_spec.rb
378
380
  - spec/aptible/cli/resource_formatter_spec.rb
379
381
  - spec/aptible/cli/subcommands/apps_spec.rb
382
+ - spec/aptible/cli/subcommands/backup_retention_policy_spec.rb
380
383
  - spec/aptible/cli/subcommands/backup_spec.rb
381
384
  - spec/aptible/cli/subcommands/config_spec.rb
382
385
  - spec/aptible/cli/subcommands/db_spec.rb
@@ -397,6 +400,7 @@ files:
397
400
  - spec/fabricators/account_fabricator.rb
398
401
  - spec/fabricators/app_fabricator.rb
399
402
  - spec/fabricators/backup_fabricator.rb
403
+ - spec/fabricators/backup_retention_policy_fabricator.rb
400
404
  - spec/fabricators/certificate_fabricator.rb
401
405
  - spec/fabricators/configuration_fabricator.rb
402
406
  - spec/fabricators/database_credential_fabricator.rb
@@ -425,7 +429,7 @@ homepage: https://github.com/aptible/aptible-cli
425
429
  licenses:
426
430
  - MIT
427
431
  metadata: {}
428
- post_install_message:
432
+ post_install_message:
429
433
  rdoc_options: []
430
434
  require_paths:
431
435
  - lib
@@ -441,7 +445,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
441
445
  version: '0'
442
446
  requirements: []
443
447
  rubygems_version: 3.1.6
444
- signing_key:
448
+ signing_key:
445
449
  specification_version: 4
446
450
  summary: Command-line interface for Aptible services
447
451
  test_files:
@@ -461,6 +465,7 @@ test_files:
461
465
  - spec/aptible/cli/renderer/text_spec.rb
462
466
  - spec/aptible/cli/resource_formatter_spec.rb
463
467
  - spec/aptible/cli/subcommands/apps_spec.rb
468
+ - spec/aptible/cli/subcommands/backup_retention_policy_spec.rb
464
469
  - spec/aptible/cli/subcommands/backup_spec.rb
465
470
  - spec/aptible/cli/subcommands/config_spec.rb
466
471
  - spec/aptible/cli/subcommands/db_spec.rb
@@ -481,6 +486,7 @@ test_files:
481
486
  - spec/fabricators/account_fabricator.rb
482
487
  - spec/fabricators/app_fabricator.rb
483
488
  - spec/fabricators/backup_fabricator.rb
489
+ - spec/fabricators/backup_retention_policy_fabricator.rb
484
490
  - spec/fabricators/certificate_fabricator.rb
485
491
  - spec/fabricators/configuration_fabricator.rb
486
492
  - spec/fabricators/database_credential_fabricator.rb
data/cleanup_bundler DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Newer rubies have Bundler 2.x installed as default so it can't be deleted
4
- # We need Bundler 1.x
5
-
6
- gempaths = `gem env gempath`.split(':')
7
- gempaths.each do |gempath|
8
- # lookup bundler-*.gemspec files and delete them
9
- # this is the only way to completely cleanup default bundler
10
- # Note: the bundler gemspecs' paths are different for CRuby and JRuby
11
- Dir.glob(gempath.strip + '/specifications/**/bundler-*.gemspec').each do |p|
12
- File.delete(p)
13
- end
14
- end