Skip to content

Instantly share code, notes, and snippets.

@pstaender
Created February 20, 2022 14:40

Revisions

  1. pstaender created this gist Feb 20, 2022.
    70 changes: 70 additions & 0 deletions update_hetzner_home_dns.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,70 @@
    require 'json'
    require 'httparty'

    class HetznerDNS
    include HTTParty
    base_uri 'https://dns.hetzner.com'

    def initialize
    @options = {
    headers: {
    'Auth-API-Token' => ENV['HETZNER_DNS']
    }
    }
    end

    def zones
    self.class.get('/api/v1/zones', @options)
    end

    def zone_by_name(name)
    zones['zones'].filter { |r| r['name'] == name }.first
    end

    def records_by_zone_id(zone_id)
    self.class.get('/api/v1/records', @options.merge({ zone_id: zone_id }))
    end

    def create_record(zone_id:, name:, type:, value:, ttl: nil)
    body = {
    name: name,
    type: type,
    value: value,
    ttl: ttl,
    zone_id: zone_id
    }
    self.class.post('/api/v1/records', @options.merge({ body: body.to_json }))
    end

    def update_record(record_id:, zone_id:, name:, type:, value:, ttl: nil)
    body = {
    name: name,
    type: type,
    value: value,
    ttl: ttl,
    zone_id: zone_id
    }
    self.class.put("/api/v1/records/#{record_id}", @options.merge({ body: body.to_json }))
    end
    end

    current_ip = HTTParty.get('https://api.ipify.org?format=json')['ip']
    subdomain = 'myhome'

    client = HetznerDNS.new
    zone_id = client.zone_by_name('mydomain.com')['id']
    record = client.records_by_zone_id(zone_id)['records'].filter { |r| r['name'] == subdomain && r['type'] == 'A' }.first

    if record
    puts "Updating dns record with ip #{current_ip}"
    pp client.update_record(
    record_id: record['id'],
    zone_id: zone_id,
    name: subdomain,
    type: 'A',
    value: current_ip
    )
    else
    puts "Creating dns record with ip #{current_ip}"
    pp client.create_record(zone_id: zone_id, name: subdomain, type: 'A', value: current_ip)
    end