Skip to content

Commit

Permalink
Add postgresql support
Browse files Browse the repository at this point in the history
  • Loading branch information
ekohl committed Jan 19, 2016
1 parent f199bc9 commit e4b9ba1
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Gemfile
@@ -1,6 +1,10 @@
source 'https://rubygems.org'
gemspec

if RUBY_VERSION.start_with? '1.8'
gem 'pg', '< 0.18.0'
end

group :development do
gem 'smart_proxy', :github => 'theforeman/smart-proxy', :branch => 'develop'
end
Expand Down
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -35,6 +35,13 @@ To use MySQL, set the following parameters:
:powerdns_mysql_password: ''
:powerdns_mysql_database: 'powerdns'

### PostgreSQL

To use PostgreSQL, set the following parameters:

:powerdns_backend: 'postgresql'
:powerdns_postgresql_connection: 'host=localhost user=powerdns password=mypassword dbname=powerdns'

### DNSSEC

In case you've enabled DNSSEC (as you should), a rectify-zone is required after every zone change. The pdnssec command is configurable:
Expand Down
42 changes: 42 additions & 0 deletions lib/smart_proxy_dns_powerdns/backend/postgresql.rb
@@ -0,0 +1,42 @@
require 'pg'

module Proxy::Dns::Powerdns::Backend
class Postgresql < ::Proxy::Dns::Powerdns::Record

attr_reader :connection_str

def initialize(a_server = nil, a_ttl = nil)
@connection_str = Proxy::Dns::Powerdns::Plugin.settings.powerdns_postgresql_connection

super(a_server, a_ttl)
end

def connection
@connection ||= PG.connect(connection_str)
end

def get_zone name
domain = nil

connection.exec_params("SELECT LENGTH(name) domain_length, id, name FROM domains WHERE $1 LIKE CONCAT('%%.', name) ORDER BY domain_length DESC LIMIT 1", [name]) do |result|
result.each do |row|
domain = row
end
end

raise Proxy::Dns::Error, "Unable to determine zone. Zone must exist in PowerDNS." unless domain

domain
end

def create_record domain_id, name, type, content
result = connection.exec_params("INSERT INTO records (domain_id, name, ttl, content, type) VALUES ($1::int, $2, $3::int, $4, $5)", [domain_id, name, ttl, content, type])
result.cmdtuples == 1
end

def delete_record domain_id, name, type
result = connection.exec_params("DELETE FROM records WHERE domain_id=$1::int AND name=$2 AND type=$3", [domain_id, name, type])
result.cmdtuples == 1
end
end
end
3 changes: 3 additions & 0 deletions lib/smart_proxy_dns_powerdns/dependencies.rb
Expand Up @@ -5,6 +5,9 @@ class Proxy::Dns::DependencyInjection::Dependencies
when 'mysql'
require 'smart_proxy_dns_powerdns/backend/mysql'
dependency :dns_provider, Proxy::Dns::Powerdns::Backend::Mysql
when 'postgresql'
require 'smart_proxy_dns_powerdns/backend/postgresql'
dependency :dns_provider, Proxy::Dns::Powerdns::Backend::Postgresql
when 'dummy'
require 'smart_proxy_dns_powerdns/backend/dummy'
dependency :dns_provider, Proxy::Dns::Powerdns::Backend::Dummy
Expand Down
Expand Up @@ -3,11 +3,13 @@
module Proxy::Dns::Powerdns
class ConfigurationValidator
def validate_settings!(settings)
validate_choice(settings, :powerdns_backend, ['mysql', 'dummy'])
validate_choice(settings, :powerdns_backend, ['mysql', 'postgresql', 'dummy'])

case settings[:powerdns_backend]
when 'mysql'
validate_presence(settings, [:powerdns_mysql_username, :powerdns_mysql_password, :powerdns_mysql_database])
when 'postgresql'
validate_presence(settings, [:powerdns_postgresql_connection])
end
end

Expand Down
1 change: 1 addition & 0 deletions smart_proxy_dns_powerdns.gemspec
Expand Up @@ -20,4 +20,5 @@ Gem::Specification.new do |s|
s.add_development_dependency('mocha')

s.add_dependency('mysql2')
s.add_dependency('pg')
end
20 changes: 20 additions & 0 deletions test/unit/dns_powerdns_configuration_validator_test.rb
Expand Up @@ -54,4 +54,24 @@ def test_initialize_mysql_with_settings
@config_validator.validate_settings!(settings)
end
end

def test_initialize_postgresql_without_settings
settings = {:dns_provider => 'powerdns', :powerdns_backend => 'postgresql'}

assert_raise Proxy::Error::ConfigurationError do
@config_validator.validate_settings!(settings)
end
end

def test_initialize_postgresql_with_settings
settings = {
:dns_provider => 'powerdns',
:powerdns_backend => 'postgresql',
:powerdns_postgresql_connection => 'dbname=powerdns'
}

assert_nothing_raised do
@config_validator.validate_settings!(settings)
end
end
end
20 changes: 20 additions & 0 deletions test/unit/dns_powerdns_record_postgresql_test.rb
@@ -0,0 +1,20 @@
require 'test_helper'

require 'smart_proxy_dns_powerdns/dns_powerdns_plugin'
require 'smart_proxy_dns_powerdns/dns_powerdns_main'
require 'smart_proxy_dns_powerdns/backend/postgresql'

class DnsPowerdnsBackendPostgresqlTest < Test::Unit::TestCase
# Test that correct initialization works
def test_initialize_dummy_with_settings
Proxy::Dns::Powerdns::Plugin.load_test_settings(:powerdns_postgresql_connection => 'dbname=powerdns')
provider = klass.new
assert_equal 'dbname=powerdns', provider.connection_str
end

private

def klass
Proxy::Dns::Powerdns::Backend::Postgresql
end
end

0 comments on commit e4b9ba1

Please sign in to comment.