module GClouder::Resources::DNS::Records
Public Class Methods
abort_transaction(args, project_id)
click to toggle source
# File lib/gclouder/resources/dns.rb, line 257 def self.abort_transaction(args, project_id) info "aborting dns record-set transaction", indent: 4 gcloud "dns record-sets transaction abort #{args}", project_id: project_id # FIXME: remove transaction file.. end
add_record_set(name, value, zone, type, ttl, project_id)
click to toggle source
FIXME: if a record exists but ttl or ip are different, an update should be performed
# File lib/gclouder/resources/dns.rb, line 273 def self.add_record_set(name, value, zone, type, ttl, project_id) if record_exists?(project_id, zone, name, type) good "#{name} IN #{type} #{value} #{ttl}", indent: 4 return end add "#{name} IN #{type} #{value} #{ttl}", indent: 4 gcloud "dns record-sets transaction add --name=#{name} --zone=#{zone} --type=#{type} --ttl=#{ttl} #{value}", project_id: project_id end
dependencies()
click to toggle source
# File lib/gclouder/resources/dns.rb, line 333 def self.dependencies return unless project.key?("dns") return unless project["dns"].key?("zones") project["dns"]["zones"].each do |zone, zone_config| project_id = zone_project_id(zone_config) zone_name = zone.tr(".", "-") # skip zone unless manage_nameservers is true next unless zone_config.key?("manage_nameservers") next unless zone_config["manage_nameservers"] # parent zone data parent_zone = zone.split(".")[1..-1].join(".") parent_zone_name = parent_zone.tr(".", "-") parent_zone_config = project["dns"]["zones"][parent_zone] # get project_id for parent zone - if it isn't set then assume the zone exists in current project parent_project_id = parent_zone_config.key?("project_id") ? parent_zone_config["project_id"] : project_id info "ensuring nameservers for zone: #{zone}, project_id: #{parent_project_id}, parent_zone: #{parent_zone}" next if cli_args[:dry_run] # find nameservers for this zone nameservers = zone_nameservers(project_id, zone_name) # ensure parent zone exists create_zone(parent_project_id, parent_zone, parent_zone_name) # create nameservers in parent zone start_transaction(parent_project_id, parent_zone_name) add_record_set zone, nameservers.join(" "), parent_zone_name, "NS", 600, parent_project_id execute_transaction(parent_project_id, parent_zone_name) end end
describe_zone(project_id, zone_name)
click to toggle source
# File lib/gclouder/resources/dns.rb, line 323 def self.describe_zone(project_id, zone_name) gcloud "--format json dns managed-zones describe #{zone_name}", project_id: project_id, force: true end
ensure(project_id, zone)
click to toggle source
# File lib/gclouder/resources/dns.rb, line 210 def self.ensure(project_id, zone) return unless zone.key?("records") start_transaction(project_id, zone["name"]) zone["records"].each do |record| next unless record_is_valid(record) values = [] if record.key?("value") && record["value"].is_a?(Array) values << record["value"].join(" ") elsif record.key?("value") && record["value"].is_a?(String) values << record["value"] elsif record.key?("static_ips") record["static_ips"].each do |ip| values << static_ip(project_id, zone["name"], ip) end else bad "no 'value' or 'static_ips' key found for record: #{record["name"]}" fatal "failure due to invalid config" end values.each do |value| unless record["name"].match(/\.$/) bad "record name missing '.' suffix: #{record["name"]}" fatal "failure due to invalid config" end ttl = record.key?("ttl") ? record["ttl"] : "300" add_record_set record["name"], value, zone["name"], record["type"], ttl, project_id end end execute_transaction(project_id, zone["name"]) end
execute_transaction(project_id, zone_name)
click to toggle source
# File lib/gclouder/resources/dns.rb, line 253 def self.execute_transaction(project_id, zone_name) gcloud "dns record-sets transaction execute --zone=#{zone_name}", project_id: project_id end
lookup_ip(name, context)
click to toggle source
# File lib/gclouder/resources/dns.rb, line 288 def self.lookup_ip(name, context) args = context == "global" ? "--global" : "--regions #{context}" ip = gcloud("compute addresses list #{name} #{args}", force: true) return false if ip.empty? ip[0]["address"] end
record_exists?(project_id, zone, name, type)
click to toggle source
# File lib/gclouder/resources/dns.rb, line 284 def self.record_exists?(project_id, zone, name, type) Resource.resource?("dns record-sets", name, "--zone=#{zone}", filter: "name = #{name} AND type = #{type}", project_id: project_id, silent: true) end
record_is_valid(record)
click to toggle source
# File lib/gclouder/resources/dns.rb, line 263 def self.record_is_valid(record) if record["type"] == "CNAME" && !record["value"].end_with?(".") info "CNAME value must end with '.'" return false end true end
start_transaction(project_id, zone_name)
click to toggle source
# File lib/gclouder/resources/dns.rb, line 249 def self.start_transaction(project_id, zone_name) gcloud "dns record-sets transaction start --zone=#{zone_name}", project_id: project_id end
static_ip(project_id, zone_name, static_ip_config)
click to toggle source
# File lib/gclouder/resources/dns.rb, line 295 def self.static_ip(project_id, zone_name, static_ip_config) %w(name context).each do |key| unless static_ip_config[key] bad "missing key '#{key}' for record" abort_transaction "--zone=#{zone_name}", project_id fatal "failure due to invalid config" end end name = static_ip_config["name"] context = static_ip_config["context"] ip = lookup_ip(name, context) unless ip unless cli_args[:dry_run] bad "ip address not found for context/name: #{context}/#{name}" abort_transaction "--zone=#{zone_name}", project_id fatal "failure due to invalid config" end # on dry runs assume the ip address has not been created but config is valid ip = "<#{context}/#{name}>" end ip end
zone_nameservers(project_id, zone_name)
click to toggle source
# File lib/gclouder/resources/dns.rb, line 327 def self.zone_nameservers(project_id, zone_name) remote_zone_definition = describe_zone(project_id, zone_name) fatal "nameservers not found for zone: #{zone_name}" unless remote_zone_definition.key?("nameServers") remote_zone_definition["nameServers"] end