first version of the script
This commit is contained in:
parent
d9236b863d
commit
6bc8cc4e1b
4 changed files with 308 additions and 3 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -12,7 +12,7 @@
|
|||
/tmp/
|
||||
|
||||
# Used by dotenv library to load environment variables.
|
||||
# .env
|
||||
.env
|
||||
|
||||
## Specific to RubyMotion:
|
||||
.dat*
|
||||
|
@ -44,9 +44,8 @@ build-iPhoneSimulator/
|
|||
# for a library or gem, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# Gemfile.lock
|
||||
# .ruby-version
|
||||
.ruby-version
|
||||
# .ruby-gemset
|
||||
|
||||
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
||||
.rvmrc
|
||||
|
||||
|
|
11
Gemfile
Normal file
11
Gemfile
Normal file
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source "https://rubygems.org"
|
||||
|
||||
# git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
||||
|
||||
gem "main"
|
||||
gem "dotenv"
|
||||
gem "aws-sdk-acm"
|
||||
gem "aws-sdk-elasticloadbalancingv2"
|
||||
gem "pry"
|
47
Gemfile.lock
Normal file
47
Gemfile.lock
Normal file
|
@ -0,0 +1,47 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
arrayfields (4.9.2)
|
||||
aws-eventstream (1.0.3)
|
||||
aws-partitions (1.226.0)
|
||||
aws-sdk-acm (1.25.0)
|
||||
aws-sdk-core (~> 3, >= 3.61.1)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-core (3.69.1)
|
||||
aws-eventstream (~> 1.0, >= 1.0.2)
|
||||
aws-partitions (~> 1.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-elasticloadbalancingv2 (1.34.0)
|
||||
aws-sdk-core (~> 3, >= 3.61.1)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sigv4 (1.1.0)
|
||||
aws-eventstream (~> 1.0, >= 1.0.2)
|
||||
chronic (0.10.2)
|
||||
coderay (1.1.2)
|
||||
dotenv (2.7.5)
|
||||
fattr (2.4.0)
|
||||
jmespath (1.4.0)
|
||||
main (6.2.3)
|
||||
arrayfields (~> 4.7, >= 4.7.4)
|
||||
chronic (~> 0.6, >= 0.6.2)
|
||||
fattr (~> 2.2, >= 2.2.0)
|
||||
map (~> 6.1, >= 6.1.0)
|
||||
map (6.6.0)
|
||||
method_source (0.9.2)
|
||||
pry (0.12.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
aws-sdk-acm
|
||||
aws-sdk-elasticloadbalancingv2
|
||||
dotenv
|
||||
main
|
||||
pry
|
||||
|
||||
BUNDLED WITH
|
||||
2.0.2
|
248
aws-cert
Executable file
248
aws-cert
Executable file
|
@ -0,0 +1,248 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
# The "main" gem is a framework for command line applications
|
||||
require "main"
|
||||
# load configuration from .env file
|
||||
require 'dotenv/load'
|
||||
# Import only the relevant AWS SDK
|
||||
require 'aws-sdk-acm'
|
||||
require 'aws-sdk-elasticloadbalancingv2'
|
||||
# Useful for debugging
|
||||
require "pry"
|
||||
|
||||
class ACM
|
||||
attr_reader :client
|
||||
|
||||
def initialize(client)
|
||||
@client = client
|
||||
end
|
||||
|
||||
# return the ARN of a certificate from its domain name
|
||||
def certificate_arn_by_domain(domain_name)
|
||||
cert_summary = client.list_certificates.certificate_summary_list.detect { |cert_summary|
|
||||
cert_summary.domain_name == domain_name
|
||||
}
|
||||
cert_summary.certificate_arn
|
||||
end
|
||||
|
||||
# return the certificate_summary_list object from AWS sdk or yields if a block is given
|
||||
def list_certificates(&block)
|
||||
response = client.list_certificates
|
||||
|
||||
if block_given?
|
||||
response.certificate_summary_list.each do |cert_summary|
|
||||
yield(cert_summary)
|
||||
end
|
||||
else
|
||||
response.certificate_summary_list
|
||||
end
|
||||
end
|
||||
|
||||
# return the certificate object from AWS sdk or yields if a block is given
|
||||
def describe_certificate(certificate_arn_or_domain_name, &block)
|
||||
certificate_arn = if acm_arn?(certificate_arn_or_domain_name)
|
||||
certificate_arn_or_domain_name
|
||||
else
|
||||
certificate_arn_by_domain(certificate_arn_or_domain_name)
|
||||
end
|
||||
|
||||
response = client.describe_certificate(certificate_arn: certificate_arn)
|
||||
certificate = response.certificate
|
||||
|
||||
if block_given?
|
||||
yield(certificate)
|
||||
else
|
||||
certificate
|
||||
end
|
||||
end
|
||||
|
||||
# return the certificate ARN of the created certificate
|
||||
def request_certificate(domain_name)
|
||||
response = client.request_certificate({
|
||||
domain_name: domain_name,
|
||||
validation_method: "DNS",
|
||||
# idempotency_token: "IdempotencyToken",
|
||||
})
|
||||
response.certificate_arn
|
||||
end
|
||||
|
||||
# return true/false if the input looks like an ACM ARN
|
||||
def acm_arn?(input)
|
||||
/\Aarn:aws:acm:/.match(input)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# print the certificate status (used in a yielded block)
|
||||
def print_certificate_status(certificate)
|
||||
puts "Domain name: #{certificate.domain_name}"
|
||||
puts " ARN: #{certificate.certificate_arn}"
|
||||
puts " Status: #{certificate.status}"
|
||||
puts " Created at: #{certificate.created_at}"
|
||||
puts " Not before: #{certificate.not_before}"
|
||||
puts " Not after: #{certificate.not_after}"
|
||||
puts " Issuer: #{certificate.issuer}"
|
||||
puts " Renewable eligibility: #{certificate.renewal_eligibility}"
|
||||
|
||||
if certificate.domain_validation_options
|
||||
certificate.domain_validation_options.each do |validation_option|
|
||||
puts " Validation option: #{validation_option.validation_method}"
|
||||
puts " Status: #{validation_option.validation_status}"
|
||||
case validation_option.validation_method
|
||||
when "DNS"
|
||||
if validation_option.resource_record
|
||||
puts " Record name: #{validation_option.resource_record.name}"
|
||||
puts " Record type: #{validation_option.resource_record.type}"
|
||||
puts " Record value: #{validation_option.resource_record.value}"
|
||||
else
|
||||
puts " Record: _unavailable_"
|
||||
end
|
||||
when "EMAIL"
|
||||
puts " Emails : #{validation_option.validation_emails}"
|
||||
end
|
||||
end
|
||||
else
|
||||
puts " Validation option: _unavailable_"
|
||||
end
|
||||
end
|
||||
|
||||
# print the certificate summary (used in a yielded block)
|
||||
def print_certificate_summary(cert_summary)
|
||||
puts "Domain name: #{cert_summary.domain_name}"
|
||||
puts " ARN: #{cert_summary.certificate_arn}"
|
||||
end
|
||||
|
||||
class ELBv2
|
||||
attr_reader :client
|
||||
def initialize(client)
|
||||
@client = client
|
||||
end
|
||||
|
||||
# return a boolean indicating if the cert has been attached to the listener
|
||||
def add_listener_certificate(listener_arn, certificate_arn)
|
||||
response = client.add_listener_certificates({
|
||||
listener_arn: listener_arn,
|
||||
certificates: [
|
||||
{
|
||||
certificate_arn: certificate_arn,
|
||||
# is_default: false,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
response.certificates.first.certificate_arn == certificate_arn
|
||||
end
|
||||
|
||||
# return the load_balancer object from AWS sdk or yields if a block is given
|
||||
def describe_load_balancer(load_balancer_arn)
|
||||
response = client.describe_load_balancers({
|
||||
load_balancer_arns: [
|
||||
load_balancer_arn
|
||||
],
|
||||
})
|
||||
load_balancer = response.load_balancers.first
|
||||
|
||||
if block_given?
|
||||
yield(load_balancer)
|
||||
else
|
||||
load_balancer
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Main {
|
||||
mode 'list' do
|
||||
def run()
|
||||
acm = ACM.new(acm_client)
|
||||
acm.list_certificates do |cert_summary|
|
||||
print_certificate_summary(cert_summary)
|
||||
end
|
||||
rescue Aws::Errors::ServiceError => ex
|
||||
exit_status exit_failure
|
||||
puts ex.message
|
||||
end
|
||||
end
|
||||
|
||||
mode 'status' do
|
||||
argument('domain') { required }
|
||||
|
||||
def run()
|
||||
domain_name = params[:domain].value
|
||||
|
||||
acm = ACM.new(acm_client)
|
||||
acm.describe_certificate(domain_name) do |certificate|
|
||||
exit_status exit_failure unless certificate.status == "ISSUED"
|
||||
print_certificate_status(certificate)
|
||||
end
|
||||
rescue Aws::Errors::ServiceError => ex
|
||||
puts "#{ex.class.name}: #{ex.message}"
|
||||
exit_failure!
|
||||
end
|
||||
end
|
||||
|
||||
mode 'create' do
|
||||
argument('domain') { required }
|
||||
|
||||
def run()
|
||||
domain_name = params[:domain].value
|
||||
|
||||
acm = ACM.new(acm_client)
|
||||
certificate_arn = acm.request_certificate(domain_name)
|
||||
|
||||
acm.describe_certificate(certificate_arn) do |certificate|
|
||||
exit_status exit_failure unless certificate.status == "ISSUED"
|
||||
print_certificate_status(certificate)
|
||||
end
|
||||
rescue Aws::Errors::ServiceError => ex
|
||||
puts "#{ex.class.name}: #{ex.message}"
|
||||
exit_failure!
|
||||
end
|
||||
end
|
||||
|
||||
mode 'enable' do
|
||||
argument('domain') { required }
|
||||
environment('ELB_ARN'){ required }
|
||||
environment('ELB_LISTENER_ARN'){ required }
|
||||
|
||||
def run()
|
||||
domain_name = params['domain'].value
|
||||
elb_arn = params['ELB_ARN'].value
|
||||
elb_listener_arn = params['ELB_LISTENER_ARN'].value
|
||||
|
||||
acm = ACM.new(acm_client)
|
||||
certificate_arn = acm.certificate_arn_by_domain(domain_name)
|
||||
certificate = acm.describe_certificate(certificate_arn)
|
||||
|
||||
if certificate.status == "ISSUED"
|
||||
elbv2 = ELBv2.new(elbv2_client)
|
||||
elbv2.add_listener_certificate(elb_listener_arn, certificate_arn)
|
||||
|
||||
elbv2.describe_load_balancer(elb_arn) do |load_balancer|
|
||||
puts "Certificate has been added to load-balancer, change DNS configuration :"
|
||||
puts " Record name: #{domain_name}."
|
||||
puts " Record type: CNAME"
|
||||
puts " Record value: #{load_balancer.dns_name}."
|
||||
end
|
||||
else
|
||||
exit_status exit_failure
|
||||
puts "Certificate for '#{domain_name}' is not available for ELB (status: #{certificate.status})"
|
||||
end
|
||||
rescue Aws::Errors::ServiceError => ex
|
||||
puts "#{ex.class.name}: #{ex.message}"
|
||||
exit_failure!
|
||||
end
|
||||
end
|
||||
|
||||
def acm_client
|
||||
args = {}
|
||||
args[:profile] = ENV['AWS_PROFILE'] if ENV['AWS_PROFILE']
|
||||
# args[:logger] = Logger.new(STDOUT)
|
||||
Aws::ACM::Client.new(args)
|
||||
end
|
||||
|
||||
def elbv2_client
|
||||
args = {}
|
||||
args[:profile] = ENV['AWS_PROFILE'] if ENV['AWS_PROFILE']
|
||||
Aws::ElasticLoadBalancingV2::Client.new(args)
|
||||
end
|
||||
}
|
Loading…
Add table
Reference in a new issue