summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--macir.rb210
1 files changed, 33 insertions, 177 deletions
diff --git a/macir.rb b/macir.rb
index a5ea61b..986312c 100644
--- a/macir.rb
+++ b/macir.rb
@@ -208,7 +208,7 @@ def wait_for_challenge_propagation(domain, challenge)
threads.each(&:join)
end
-def acme_request_with_retries(retries: 5, &block)
+def acme_request_with_retries(retries: 10, &block)
# p "Retries: #{retries}"
block.call(self)
rescue Acme::Client::Error::BadNonce
@@ -218,6 +218,15 @@ rescue Acme::Client::Error::BadNonce
acme_request_with_retries(retries: retries - 1, &block)
end
+def unvalidated_domains(d_a)
+ d_a.select do |d, a|
+ p "#{d} status #{a['auth'].dns01.status}"
+ p a['auth'].dns01.status
+ acme_request_with_retries { a['auth'].dns01.reload }
+ a['auth'].dns01.status != 'valid'
+ end
+end
+
def wait_for_challenge_validation(challenge, cert_name)
p 'Requesting validation of challenge'
p challenge.object_id
@@ -308,121 +317,17 @@ def handle_apex_authzs(apex, authzs, config)
end
-# domain_to_apex = {}
-#
-# domain_apex_threads = []
-# domains_with_apex = domains.map do |domain|
-# apex_thread = Thread.new(domain) do |d|
-# find_apex_domain(d).to_s
-# end
-# domain_apex_threads << apex_thread
-# domain_to_apex[domain] = apex_thread.value
-# { apex_thread.value => [domain] }
-# end
-# domain_apex_threads.each(&:join)
-#
-# domains_per_apex = domains_with_apex[0].merge(*domains_with_apex[1..]) do |_key, old, new|
-# old + new
-# end
-#
-# p "domains_per_apex"
-# pp domains_per_apex
-
-
config = read_config
cert_dir = config.dig('global', 'cert_dir') || './certs/'
ensure_cert_dir(cert_dir)
-# acme_threads = []
-# # iterate over configured certs
-# config['certs'].each_pair do |cert_name, cert_opts|
-# acme_threads << Thread.new(cert_name, cert_opts) do |cert_name, cert_opts|
-# ensure_cert_dir(cert_dir + cert_name)
-#
-# p "Cert #{cert_name}: Finding CA to use for cert"
-# cert_ca = cert_opts['ca'] || config.dig('defaults', 'certs', 'ca')
-# cert_ca_name = cert_ca['name']
-# cert_ca_account_name = cert_ca['account']
-#
-# p "Cert #{cert_name}: Finding directory URL for CA"
-# acme_directory_url = config.dig('CAs', cert_ca_name, 'directory_url')
-#
-# p "Cert #{cert_name}: Finding account to use for cert #{cert_name} from CA #{cert_ca_name}"
-# account = config.dig('ca_accounts', cert_ca_account_name)
-# email = account['email']
-#
-# private_key = read_account_key(account['keyfile'])
-#
-# p "Cert #{cert_name}: Creating client object for communication with CA"
-# client = Acme::Client.new(private_key: private_key, directory: acme_directory_url)
-#
-# acme_request_with_retries { client.new_account(contact: "mailto:#{email}", terms_of_service_agreed: true) }
-#
-# p "Cert #{cert_name}: Creating order object for cert #{cert_name}"
-# order = acme_request_with_retries { client.new_order(identifiers: cert_opts['domain_names']) }
-#
-# p "Cert #{cert_name}: order status"
-# p order.status
-#
-# if order.status != 'ready'
-# p "Cert #{cert_name}: Order is not ready, we need to authorize first"
-#
-# # TODO: collect dns modifications per primary NS, update all at once
-# p "Cert #{cert_name}: Iterating over required authorizations"
-# auths = acme_request_with_retries { order.authorizations }
-# auths.each do |auth|
-# p "Cert #{cert_name}: Processing authorization for #{auth.domain}"
-# p "Cert #{cert_name}: Finding challenge type for #{auth.domain}"
-# # p "Cert #{cert_name}: auth is:"
-# # pp auth
-# if auth.status == 'valid'
-# p "Cert #{cert_name}: Authorization for #{auth.domain} is still valid, skipping"
-# next
-# end
-#
-# challenge = auth.dns01
-# primary_ns = config.dig('domains', auth.domain, 'primary_ns') || config.dig('defaults', 'domains', 'primary_ns')
-# deploy_dns01_challenge_token(auth.domain, challenge, primary_ns, config)
-# wait_for_challenge_propagation(auth.domain, challenge)
-# wait_for_challenge_validation(challenge, cert_name)
-# end
-# else
-# p "Cert #{cert_name}: Order is ready, we don’t need to authorize"
-# end
-# domain_key = read_cert_key(cert_name)
-#
-# get_cert(order, cert_name, cert_opts['domain_names'], domain_key)
-# end
-# end
-#
-# acme_threads.each(&:join)
-
-
-# TODO: restructure process
-# DELAY THIS FOR NOW: check all certs’ lifetimes
-# DELAY THIS FOR NOW: decide which ones to renew
-# collect domain names for certs to be renewed
-# group domains in need of validation by apex_domain
-# collect ca_accounts that need to be used
-# THREAD PER ACCOUNT: create account object
-# hash: ca_account => account object
-# THREAD PER CA_ACCOUNT: create orders
-# THREAD PER DOMAIN: check validation status and collect domains needing validation
-# THREAD PER APEX DOMAIN:
- # THREAD PER DOMAIN: request challenge
- # deploy challenges with one DNS UPDATE per apex_domain
- # THREAD PER NS: check propagation
- # THREAD PER DOMAIN:
- # request validation
- # report back to main
-# THREAD PER CERT: when all domains for any cert are validated, finalize order
-
domains = config['certs'].map { |_certname, cert_opts| cert_opts['domain_names'] }.flatten
domain_attrs = domains.to_h { |d| [d, {}] }
+
domain_apex_threads = {}
domains.map do |d|
domain_apex_threads[d] = Thread.new(d) do |d|
@@ -467,24 +372,6 @@ certs.each_pair do |name, opts|
opts['ca_account'] || certs[name]['ca_account'] = config.dig('defaults', 'certs', 'ca_account')
end
-# # iterate over configured certs to find CA and account to use
-# cert_to_CA_account = config['certs'].map do |cert_name, cert_opts|
-# # ensure_cert_dir(cert_dir + cert_name)
-#
-# p "Cert #{cert_name}: Finding CA to use for cert"
-# find_ca_for_cert(cert_name, cert_opts, config)
-# end
-#
-# # p "cert_to_CA_account"
-# # pp cert_to_CA_account
-#
-# certs_to_CA = cert_to_CA_account[0].merge(*cert_to_CA_account[1..])
-# # p "certs_to_CA"
-# # p certs_to_CA
-
-
-# unique_CA_accounts_to_use = certs_to_CA.values.uniq
-# p "unique_CA_accounts_to_use: #{unique_CA_accounts_to_use}"
ca_accounts = certs.map { |_, opts| opts['ca_account'] }.uniq
@@ -507,20 +394,9 @@ account_threads.each(&:join)
ca_clients = account_threads.map { |t| t.value }
ca_clients = ca_clients[0].merge(*ca_clients[1..])
-# ca_clients = {}
-# account_threads.each do |t|
-# ca_account_to_client = t.value
-# ca_clients[ca_account_to_client['account']] = ca_account_to_client['client']
-# end
-
-# acme_threads = []
certs.each_pair do |cert_name, cert_opts|
- # p cert_opts
- # p cert_opts['ca_account']
client = ca_clients[cert_opts['ca_account']]
- # p "client"
- # p client
domains = cert_opts['domain_names']
certs[cert_name]['order_thread'] = Thread.new(cert_name, client, domains) do |cert_name, client, domains|
p "Cert #{cert_name}: Creating order object for cert #{cert_name}"
@@ -534,41 +410,10 @@ certs.each_pair do |cert_name, cert_opts|
certs[cert_name]['order'] = t.value
end
-# pp certs
-
-# certs_to_CA.each_pair do |cert_name, ca|
-# # p "ca_clients[ca]: #{ca_clients[ca]}"
-# acme_threads << Thread.new(cert_name, ca_clients[ca], config) do |cert_name, client, config|
-# p "Cert #{cert_name}: Creating order object for cert #{cert_name}"
-# cert_opts = config['certs'][cert_name]
-# order = acme_request_with_retries { client.new_order(identifiers: cert_opts['domain_names']) }
-# { cert_name => order }
-# end
-# end
-#
-# acme_threads.each(&:join)
-# orders = acme_threads.map(&:value)
-# orders = orders[0].merge(*orders[1..])
-# p "orders:"
-# pp orders
-
-# order_threads = []
-# # for each order do
-# # if its ready skip to getting cert
-# # THREADS: get authorizations
-# authorizations = {}
-# orders.each_pair do |cert_name, order|
-# order_authorizations = acme_request_with_retries { order.authorizations }
-# authorizations[cert_name] = order_authorizations
-# end
certs.each_pair do |cert, opts|
order_authorizations = acme_request_with_retries { opts['order'].authorizations }
order_authorizations.each do |auth|
- # pp auth
- # pp auth.domain
- # pp auth.challenges
- # pp auth.url
domain_attrs[auth.domain]['auth'] = auth
end
end
@@ -595,20 +440,31 @@ end
propagation_threads.each(&:join)
-validation_threads = {}
-domain_attrs.each_pair do |d, attrs|
- # domain_attrs[d][:auth_thread] = Thread.new(attrs) do |attrs|
- # validation_threads[d] = Thread.new(attrs) do |attrs|
- # wait_for_challenge_validation(auth.domain, auth.dns01)
- # pp auth.dns01
- # pp auth.dns01
- # p attrs['auth'].object_id
- wait_for_challenge_validation(attrs['auth'].dns01, attrs['auth'].domain)
- # end
+# validation_threads = {}
+p 'Finding unvalidated domains, initial run'
+unvalidated_domains = unvalidated_domains(domain_attrs)
+until unvalidated_domains.empty?
+ unvalidated_domains.each_pair do |_, attrs|
+ # WARNING: for some reason threading does not really work here!
+ # domain_attrs.each_pair do |d, attrs|
+ # domain_attrs[d][:auth_thread] = Thread.new(attrs) do |attrs|
+ # validation_threads[d] = Thread.new(attrs) do |attrs|
+ # wait_for_challenge_validation(auth.domain, auth.dns01)
+ # pp auth.dns01
+ # pp auth.dns01
+ # p attrs['auth'].object_id
+ # wait_for_challenge_validation(attrs['auth'].dns01, attrs['auth'].domain)
+ # acme_request_with_retries { attrs['auth'].dns01.reload }
+ p 'Requesting validation of challenge'
+ acme_request_with_retries { attrs['auth'].dns01.request_validation }
+ end
# validation_threads[d] = domain_attrs[d][:auth_thread]
+ p 'Finding unvalidated domains, next run'
+ unvalidated_domains = unvalidated_domains(domain_attrs)
+ sleep(0.2)
end
-validation_threads.each_pair { |d, t| t.join }
+# validation_threads.each_pair { |d, t| t.join }
certs.each_pair do |name, opts|
cert_key = read_cert_key(name)