Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added maintenance deadline to CLI in printouts #322

Merged
merged 11 commits into from
Aug 24, 2023
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ Commands:
aptible login # Log in to Aptible
aptible logs [--app APP | --database DATABASE] # Follows logs from a running app or database
aptible logs_from_archive --bucket NAME --region REGION --stack NAME [ --decryption-keys ONE [OR MORE] ] [ --download-location LOCATION ] [ [ --string-matches ONE [OR MORE] ] | [ --app-id ID | --database-id ID | --endpoint-id ID | --container-id ID ] [ --start-date YYYY-MM-DD --end-date YYYY-MM-DD ] ] --bucket=BUCKET --region=REGION --stack=STACK # Retrieves container logs from an S3 archive in your own AWS account. You must provide your AWS credentials via the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
aptible maintenance:apps # List Apps impacted by maintenance schedules where restarts are required
aptible maintenance:dbs # List Databases impacted by maintenance schedules where restarts are required
aptible metric_drain:create:datadog HANDLE --api_key DATADOG_API_KEY --site DATADOG_SITE --environment ENVIRONMENT # Create a Datadog Metric Drain
aptible metric_drain:create:influxdb HANDLE --db DATABASE_HANDLE --environment ENVIRONMENT # Create an InfluxDB Metric Drain
aptible metric_drain:create:influxdb:custom HANDLE --username USERNAME --password PASSWORD --url URL_INCLUDING_PORT --db INFLUX_DATABASE_NAME --environment ENVIRONMENT # Create an InfluxDB Metric Drain
Expand Down
2 changes: 1 addition & 1 deletion aptible-cli.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
spec.require_paths = ['lib']

spec.add_dependency 'aptible-resource', '~> 1.1'
spec.add_dependency 'aptible-api', '~> 1.2'
spec.add_dependency 'aptible-api', '~> 1.4'
spec.add_dependency 'aptible-auth', '~> 1.2.4'
spec.add_dependency 'aptible-billing', '~> 1.0'
spec.add_dependency 'thor', '~> 0.20.0'
Expand Down
5 changes: 5 additions & 0 deletions lib/aptible/cli/agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
require_relative 'helpers/config_path'
require_relative 'helpers/log_drain'
require_relative 'helpers/metric_drain'
require_relative 'helpers/date_helpers'
require_relative 'helpers/s3_log_helpers'
require_relative 'helpers/maintenance'

require_relative 'subcommands/apps'
require_relative 'subcommands/config'
Expand All @@ -39,6 +41,7 @@
require_relative 'subcommands/endpoints'
require_relative 'subcommands/log_drain'
require_relative 'subcommands/metric_drain'
require_relative 'subcommands/maintenance'

module Aptible
module CLI
Expand All @@ -49,6 +52,7 @@ class Agent < Thor
include Helpers::Ssh
include Helpers::System
include Helpers::ConfigPath
include Helpers::DateHelpers
include Subcommands::Apps
include Subcommands::Config
include Subcommands::DB
Expand All @@ -65,6 +69,7 @@ class Agent < Thor
include Subcommands::Endpoints
include Subcommands::LogDrain
include Subcommands::MetricDrain
include Subcommands::Maintenance

# Forward return codes on failures.
def self.exit_on_failure?
Expand Down
26 changes: 26 additions & 0 deletions lib/aptible/cli/helpers/date_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module Aptible
module CLI
module Helpers
module DateHelpers
def utc_date(date_string)
t_fmt = '%Y-%m-%d %Z'
Time.strptime("#{date_string} UTC", t_fmt)
rescue ArgumentError
raise Thor::Error, 'Please provide dates in YYYY-MM-DD format'
end

def utc_datetime(datetime_string)
Time.parse("#{datetime_string}Z")
rescue ArgumentError
nil
end

def utc_string(datetime_string)
Time.parse("#{datetime_string}Z").utc
rescue ArgumentError
nil
end
end
end
end
end
19 changes: 19 additions & 0 deletions lib/aptible/cli/helpers/maintenance.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'aptible/api'

module Aptible
module CLI
module Helpers
module Maintenance
include Helpers::Token

def maintenance_apps
Aptible::Api::MaintenanceApp.all(token: fetch_token)
madhuravius marked this conversation as resolved.
Show resolved Hide resolved
end

def maintenance_databases
Aptible::Api::MaintenanceDatabase.all(token: fetch_token)
end
end
end
end
end
15 changes: 2 additions & 13 deletions lib/aptible/cli/helpers/s3_log_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ module Aptible
module CLI
module Helpers
module S3LogHelpers
include Helpers::DateHelpers

def ensure_aws_creds
cred_errors = []
unless ENV['AWS_ACCESS_KEY_ID']
Expand Down Expand Up @@ -190,19 +192,6 @@ def time_match?(time_range, start_timestamp, end_timestamp)
true
end

def utc_date(date_string)
t_fmt = '%Y-%m-%d %Z'
Time.strptime("#{date_string} UTC", t_fmt)
rescue ArgumentError
raise Thor::Error, 'Please provide dates in YYYY-MM-DD format'
end

def utc_datetime(datetime_string)
Time.parse("#{datetime_string}Z")
rescue ArgumentError
nil
end

def encryption_key(filesum, possible_keys)
# The key can be determined from the sum
possible_keys.each do |k|
Expand Down
24 changes: 24 additions & 0 deletions lib/aptible/cli/resource_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module Aptible
module CLI
module ResourceFormatter
class << self
include Helpers::DateHelpers

NO_NESTING = Object.new.freeze

def inject_backup(node, backup, include_db: false)
Expand Down Expand Up @@ -235,6 +237,28 @@ def inject_metric_drain(node, metric_drain, account)
attach_account(node, account)
end

def inject_maintenance(
node,
command_prefix,
maintenance_resource,
account
)
node.value('id', maintenance_resource.id)
raw_start, raw_end = maintenance_resource.maintenance_deadline
window_start = utc_string(raw_start)
window_end = utc_string(raw_end)
label = "#{maintenance_resource.handle} between #{window_start} "\
"and #{window_end}"
restart_command = "#{command_prefix}"\
" #{maintenance_resource.handle}"\
" --environment #{account.handle}"
node.value('label', label)
node.value('handle', maintenance_resource.handle)
node.value('restart_command', restart_command)

attach_account(node, account)
end

private

def attach_account(node, account)
Expand Down
2 changes: 1 addition & 1 deletion lib/aptible/cli/subcommands/logs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def self.included(thor)
thor.class_eval do
include Helpers::Operation
include Helpers::AppOrDatabase
include Helpers::S3LogHelpers
include Helpers::DateHelpers

desc 'logs [--app APP | --database DATABASE]',
'Follows logs from a running app or database'
Expand Down
97 changes: 97 additions & 0 deletions lib/aptible/cli/subcommands/maintenance.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
module Aptible
module CLI
module Subcommands
module Maintenance
def self.included(thor)
thor.class_eval do
include Helpers::Environment
include Helpers::Maintenance
include Helpers::Token

desc 'maintenance:apps',
'List Apps impacted by maintenance schedules where '\
'restarts are required'
option :environment
define_method 'maintenance:apps' do
found_maintenance = false
m = maintenance_apps
Formatter.render(Renderer.current) do |root|
root.grouped_keyed_list(
{ 'environment' => 'handle' },
'label'
) do |node|
scoped_environments(options).each do |account|
m.select { |app| app.account.id == account.id }
.each do |app|
next unless app.maintenance_deadline
found_maintenance = true
node.object do |n|
ResourceFormatter.inject_maintenance(
n,
'aptible restart --app',
app,
account
)
end
end
end
end
end
if found_maintenance
explanation 'app'
else
no_maintenances 'app'
end
end
desc 'maintenance:dbs',
'List Databases impacted by maintenance schedules where '\
'restarts are required'
option :environment
define_method 'maintenance:dbs' do
found_maintenance = false
m = maintenance_databases
Formatter.render(Renderer.current) do |root|
root.grouped_keyed_list(
{ 'environment' => 'handle' },
'label'
) do |node|
scoped_environments(options).each do |account|
m.select { |db| db.account.id == account.id }
.each do |db|
next unless db.maintenance_deadline
found_maintenance = true
node.object do |n|
ResourceFormatter.inject_maintenance(
n,
'aptible db:restart',
db,
account
)
end
end
end
end
end
if found_maintenance
explanation 'database'
else
no_maintenances 'database'
end
end
end
end

def explanation(resource_type)
CLI.logger.warn "\nYou may restart these #{resource_type}(s)"\
' at any time, or Aptible will restart it'\
' during the defined window.'
end

def no_maintenances(resource_type)
CLI.logger.info "\nNo #{resource_type}s found affected "\
'by maintenance schedules.'
end
end
end
end
end
Loading