Add an initial prototype of zonespec for verifying DNS servers

This commit is contained in:
R. Tyler Croy 2017-01-17 20:36:01 -08:00
parent 3b39046bdc
commit 261730e5fd
No known key found for this signature in database
GPG Key ID: 1426C7DC3F51E16F
16 changed files with 256 additions and 2 deletions

2
.gitignore vendored
View File

@ -7,3 +7,5 @@
/pkg/
/spec/reports/
/tmp/
*.sw*
.ruby-*

View File

@ -1,2 +1,6 @@
require "bundler/gem_tasks"
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new
task :default => :spec

View File

@ -1,5 +1,4 @@
require "zonespec/version"
module Zonespec
# Your code goes here...
end

View File

@ -0,0 +1,18 @@
require 'zonespec'
require 'zonefile'
module Zonespec
class DNS_Server
attr_reader :hostname
def initialize(hostname)
@hostname = hostname
@zonefile = nil
end
def to_s
return "DNS Server at #{hostname}"
end
end
end

52
lib/zonespec/rspec.rb Normal file
View File

@ -0,0 +1,52 @@
require 'zonespec'
require 'zonespec/dns_server'
require 'zonespec/zone_handler'
module Zonespec
module RSpec
module Global
def dns_server(*args)
Zonespec::DNS_Server.new(*args)
end
end
module Nested
def zone(*args)
@@zone_name = args.first
if args.size > 1
@@zone_file = args.last
end
Zonespec::ZoneHandler.new(@@zone_name,
self.described_class.hostname)
end
def verify_all_cnames!
zf = Zonefile.from_file(@@zone_file)
zf.cname.each do |cname|
host = cname[:host]
if host == '@'
host = "#{@@zone_name}."
end
it { should serve_cname(cname[:name], host) }
end
end
end
end
end
extend Zonespec::RSpec::Global
class RSpec::Core::ExampleGroup
extend Zonespec::RSpec::Nested
end
RSpec::Matchers.define :serve_cname do |name, host|
match do |zone|
raise "Must use within zone()" unless zone.kind_of? Zonespec::ZoneHandler
zone.serves_cname?(name, host)
end
description do |zone|
"serve the CNAME `#{name}` for `#{host}`"
end
end

View File

@ -0,0 +1,35 @@
require 'zonespec'
require 'dnsruby'
module Zonespec
class ZoneHandler
def initialize(name, dns_server)
@zone_name = name
@dns_server = dns_server
end
def to_s
return "Zone for #{@zone_name}"
end
def serves_cname?(name, host)
fqdn = "#{name}.#{@zone_name}"
fqdn_alias = "#{host}.#{@zone_name}"
begin
resolver = Dnsruby::Resolver.new
resolver.nameserver = @dns_server
r = resolver.query(fqdn, 'CNAME', 'IN')
answers = r.answer.select { |a| a.type == 'CNAME' }
if host.end_with? '.'
answers.first.domainname.to_s == host[0 ... -1]
else
answers.first.domainname.to_s == fqdn_alias
end
rescue Exception => e
puts e
false
end
end
end
end

BIN
spec/.spec_helper.rb.swp Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,26 @@
; Domain: example.com
; SOA Record
@ 1D IN SOA ns1.linux.com. rspec.linux.com. (
2017011701 ; serial, todays date + todays serial #
28800 ; refresh, seconds
7200 ; retry, seconds
604800 ; expire, seconds
3600 ; minimum, seconds
)
; A Records
@ 3600 IN A 127.0.0.1 ; lol
; CNAME Records
www 3600 IN CNAME @
ftp 3600 IN CNAME www
; NS Records
@ 3600 IN NS ns1.linux.com.
; spam trap
mx 3600 IN MX 10 mxa.linux.com.
@ 3600 MX 10 mxa.linux.com.

View File

@ -0,0 +1,24 @@
require 'spec_helper'
require 'zonespec/rspec'
describe dns_server('8.8.8.8') do
describe zone('jenkins.io', 'spec/acceptance/jenkins.io.zone') do
verify_all_cnames!
end
describe zone('jenkins.io') do
it { should serve_cname('www', 'jenkins.io.') }
end
end
describe dns_server('localhost') do
describe zone('example.com', 'spec/acceptance/example.com.zone') do
#verify_all_cnames!
end
describe zone('example.com') do
#it { pending "Need to get a local test server set up"; should serve_cname('ftp', 'www') }
end
end

View File

@ -0,0 +1,84 @@
; Domain: jenkins.io
; SOA Record
@ 1D IN SOA ns1.jenkins-ci.org. tyler.monkeypox.org. (
2015122201 ; serial, todays date + todays serial #
28800 ; refresh, seconds
7200 ; retry, seconds
604800 ; expire, seconds
3600 ; minimum, seconds
)
; A Records
@ 3600 IN A 140.211.15.101 ; eggplant
; Physical machine at Contegix
cucumber 3600 IN A 199.193.196.24
; VM at Rackspace
celery 3600 IN A 162.242.234.101
celery 3600 IN AAAA 2001:4802:7801:103:be76:4eff:fe20:357c
okra 3600 IN A 162.209.106.32
okra 3600 IN AAAA 2001:4802:7800:2:be76:4eff:fe20:7a31
; cabbage has died of dysentery
cabbage 3600 IN A 104.130.167.56
kelp 3600 IN A 162.209.124.149
kelp 3600 IN AAAA 2001:4802:7801:101:be76:4eff:fe20:b252
; Hosts at OSUOSL
lettuce 3600 IN A 140.211.9.32 ; otherwise known as jenkins-lettuce.osuosl.org
; artichoke has died of dysentery
artichoke 3600 IN A 140.211.9.22 ; otherwise known as jenkins-puppet.osuosl.org
eggplant 3600 IN A 140.211.15.101 ; otherwise known as hudson-java.osuosl.org
edamame 3600 IN A 140.211.9.2 ; otherwise known as jenkins-confluence.osuosl.org
radish 3600 IN A 140.211.9.94 ; otherwise known as jenkins-radish.osuosl.org
; EC2
ldap 3600 IN A 52.201.145.189 ; jenkins-ldap
rating 3600 IN A 52.23.130.110 ; jenkins-ratings
mirrors 3600 IN A 52.202.51.185 ; jenkins-mirrorbrain
ci 3600 IN A 52.71.231.250 ; jenkins-ci
l10n 3600 IN A 52.71.7.244 ; jenkins-l10n
census 3600 IN A 52.202.38.86 ; jenkins-census
usage 3600 IN A 52.204.62.78 ; jenkins-usage
; CNAME Records
www 3600 IN CNAME @
pkg 3600 IN CNAME mirrors ; pkg and mirrors run off the same host
beta 3600 IN CNAME eggplant ; beta site for the jenkins-ci.org/jenkins.io site
puppet 3600 IN CNAME radish
accounts 3600 IN CNAME eggplant
updates 3600 IN CNAME mirrors ; updates.jenkins.io for delivering update center, etc
archives 3600 IN CNAME okra ; archives.jenkins.io for delivering old releases
;fallback 3600 IN CNAME spinach ; fallback.jenkins.io for acting as a fallback mirror
stats 3600 IN CNAME jenkins-infra.github.io. ; CNAME for stats.jenkins.io which is hosted on GH pages
patron 3600 IN CNAME jenkins-infra.github.io. ; CNAME for patron.jenkins.io which is hosted on GH pages
javadoc 3600 IN CNAME eggplant ; CNAME for javadoc.jenkins.io which is currently in role::eggplant
plugins 3600 IN CNAME kelp ; plugins.jenkins.io runs a simple pluginsite
; Magical CNAME for certificate validation
D07F852F584FA592123140354D366066.ldap.jenkins.io. 3600 IN CNAME 75E741181A7ACDBE2996804B2813E09B65970718.comodoca.com.
; Amazon SES configuration to send out email from noreply@jenkins.io
_amazonses 3600 IN TXT "kYNeW+b+9GnKO/LzqP/t0TzLyN86jQ9didoBAJSjezE="
pbssnl2yyudgfdl3flznotnarnamz5su._domainkey 3600 IN CNAME pbssnl2yyudgfdl3flznotnarnamz5su.dkim.amazonses.com.
6ch6fw67efpfgoqyhdhs2cy2fpkwrvsk._domainkey 3600 IN CNAME 6ch6fw67efpfgoqyhdhs2cy2fpkwrvsk.dkim.amazonses.com.
37qo4cqmkxeocwr2iicjop77fq52m6yh._domainkey 3600 IN CNAME 37qo4cqmkxeocwr2iicjop77fq52m6yh.dkim.amazonses.com.
; NS Records
@ 3600 IN NS ns1.jenkins-ci.org.
@ 3600 IN NS ns2.jenkins-ci.org.
@ 3600 IN NS ns3.jenkins-ci.org.
; spam trap
spamtrap 3600 IN MX 10 mxa.mailgun.org.
spamtrap 3600 IN MX 10 mxb.mailgun.org.
; mailgun configuration
@ 3600 IN TXT "v=spf1 include:mailgun.org ~all"
mailo._domainkey 3600 IN TXT "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpS+8K+bVvFlfTqbVbuvM9SoX0BqjW3zK7BJeCZ4GnaJTeRaurKx81hUX1wz3wKt+Qt9xI+X6mAlar2Co+B13GsNZIlYVdO/zBVtZG+R5KvMQUynNyie05oRyaTFWtNEiQVgGYgM4xkwlIWSA9EXmBMaKg7ze3kKNKUOnzKDIxMQIDAQAB"
@ 3600 MX 10 mxa.mailgun.org.
@ 3600 MX 10 mxb.mailgun.org.

8
spec/spec_helper.rb Normal file
View File

@ -0,0 +1,8 @@
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '../lib'))
require 'pry'
RSpec.configure do |c|
c.color = true
c.order = "random"
end

View File

@ -28,7 +28,9 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "bundler", "~> 1.12"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rspec"
spec.add_development_dependency "pry"
spec.add_dependency 'zonefile', '~> 1.04'
spec.add_dependency 'serverspec', '~> 2.38'
spec.add_dependency 'dnsruby', '~> 1.60'
end