first version of the script
This commit is contained in:
parent
d9236b863d
commit
6bc8cc4e1b
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -12,7 +12,7 @@
|
||||||
/tmp/
|
/tmp/
|
||||||
|
|
||||||
# Used by dotenv library to load environment variables.
|
# Used by dotenv library to load environment variables.
|
||||||
# .env
|
.env
|
||||||
|
|
||||||
## Specific to RubyMotion:
|
## Specific to RubyMotion:
|
||||||
.dat*
|
.dat*
|
||||||
|
@ -44,9 +44,8 @@ build-iPhoneSimulator/
|
||||||
# for a library or gem, you might want to ignore these files since the code is
|
# 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:
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
# Gemfile.lock
|
# Gemfile.lock
|
||||||
# .ruby-version
|
.ruby-version
|
||||||
# .ruby-gemset
|
# .ruby-gemset
|
||||||
|
|
||||||
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
||||||
.rvmrc
|
.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…
Reference in a new issue