sml-rubber 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. data/COPYING +339 -0
  2. data/README +6 -0
  3. data/TODO +9 -0
  4. data/VERSION +1 -0
  5. data/generators/vulcanize/USAGE +6 -0
  6. data/generators/vulcanize/templates/apache/config/rubber/deploy-apache.rb +45 -0
  7. data/generators/vulcanize/templates/apache/config/rubber/role/web/deflate.conf +10 -0
  8. data/generators/vulcanize/templates/apache/config/rubber/role/web/expires.conf +9 -0
  9. data/generators/vulcanize/templates/apache/config/rubber/role/web/headers.conf +6 -0
  10. data/generators/vulcanize/templates/apache/config/rubber/role/web/setenvif.conf +52 -0
  11. data/generators/vulcanize/templates/apache/config/rubber/role/web/vhost.conf +27 -0
  12. data/generators/vulcanize/templates/apache/config/rubber/rubber-apache.yml +15 -0
  13. data/generators/vulcanize/templates/apache/templates.yml +1 -0
  14. data/generators/vulcanize/templates/base/Capfile +17 -0
  15. data/generators/vulcanize/templates/base/config/deploy.rb +77 -0
  16. data/generators/vulcanize/templates/base/config/rubber/common/crontab +16 -0
  17. data/generators/vulcanize/templates/base/config/rubber/common/profile.rc +9 -0
  18. data/generators/vulcanize/templates/base/config/rubber/deploy-setup.rb +56 -0
  19. data/generators/vulcanize/templates/base/config/rubber/rubber.yml +221 -0
  20. data/generators/vulcanize/templates/base/lib/tasks/rubber.rake +18 -0
  21. data/generators/vulcanize/templates/base/script/cron-rake +18 -0
  22. data/generators/vulcanize/templates/base/script/cron-runner +18 -0
  23. data/generators/vulcanize/templates/base/script/cron-sh +67 -0
  24. data/generators/vulcanize/templates/base/templates.yml +1 -0
  25. data/generators/vulcanize/templates/complete_mysql/templates.yml +6 -0
  26. data/generators/vulcanize/templates/complete_passenger_mysql/templates.yml +8 -0
  27. data/generators/vulcanize/templates/cruise/config/rubber/deploy-cruise.rb +74 -0
  28. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/cruise +40 -0
  29. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/my.cnf +165 -0
  30. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/production.rb +8 -0
  31. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/site_config.rb +76 -0
  32. data/generators/vulcanize/templates/cruise/config/rubber/role/web_tools/cruise-nginx.conf +11 -0
  33. data/generators/vulcanize/templates/cruise/config/rubber/rubber-cruise.yml +18 -0
  34. data/generators/vulcanize/templates/cruise/templates.yml +1 -0
  35. data/generators/vulcanize/templates/haproxy/config/rubber/deploy-haproxy.rb +45 -0
  36. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/haproxy-default.conf +8 -0
  37. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/haproxy.conf +44 -0
  38. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/monit-haproxy.conf +9 -0
  39. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/syslog-haproxy.conf +6 -0
  40. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/syslogd-default.conf +17 -0
  41. data/generators/vulcanize/templates/haproxy/config/rubber/role/web_tools/haproxy-nginx.conf +10 -0
  42. data/generators/vulcanize/templates/haproxy/config/rubber/rubber-haproxy.yml +12 -0
  43. data/generators/vulcanize/templates/haproxy/templates.yml +1 -0
  44. data/generators/vulcanize/templates/memcached/config/memcached.yml +28 -0
  45. data/generators/vulcanize/templates/memcached/config/rubber/common/memcached.yml +14 -0
  46. data/generators/vulcanize/templates/memcached/config/rubber/role/memcached/memcached.conf +52 -0
  47. data/generators/vulcanize/templates/memcached/config/rubber/role/memcached/memcached_munin_plugin +249 -0
  48. data/generators/vulcanize/templates/memcached/config/rubber/rubber-memcached.yml +7 -0
  49. data/generators/vulcanize/templates/memcached/templates.yml +1 -0
  50. data/generators/vulcanize/templates/minimal_mysql/templates.yml +7 -0
  51. data/generators/vulcanize/templates/minimal_nodb/templates.yml +6 -0
  52. data/generators/vulcanize/templates/mongrel/config/rubber/deploy-mongrel.rb +75 -0
  53. data/generators/vulcanize/templates/mongrel/config/rubber/role/app/mongrel_cluster.yml +12 -0
  54. data/generators/vulcanize/templates/mongrel/config/rubber/role/app/monit-mongrel.conf +20 -0
  55. data/generators/vulcanize/templates/mongrel/config/rubber/rubber-mongrel.yml +9 -0
  56. data/generators/vulcanize/templates/mongrel/templates.yml +1 -0
  57. data/generators/vulcanize/templates/monit/config/rubber/common/monit-default.conf +15 -0
  58. data/generators/vulcanize/templates/monit/config/rubber/common/monit.conf +251 -0
  59. data/generators/vulcanize/templates/monit/config/rubber/deploy-monit.rb +32 -0
  60. data/generators/vulcanize/templates/monit/config/rubber/role/web_tools/monit-admin-nginx.conf +10 -0
  61. data/generators/vulcanize/templates/monit/config/rubber/rubber-monit.yml +6 -0
  62. data/generators/vulcanize/templates/monit/templates.yml +1 -0
  63. data/generators/vulcanize/templates/munin/config/rubber/common/monit-munin.conf +8 -0
  64. data/generators/vulcanize/templates/munin/config/rubber/common/munin-node.conf +48 -0
  65. data/generators/vulcanize/templates/munin/config/rubber/deploy-munin.rb +30 -0
  66. data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin-nginx.conf +8 -0
  67. data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin-plugins.conf +31 -0
  68. data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin.conf +80 -0
  69. data/generators/vulcanize/templates/munin/config/rubber/rubber-munin.yml +8 -0
  70. data/generators/vulcanize/templates/munin/script/munin/example_mysql_query.rb +57 -0
  71. data/generators/vulcanize/templates/munin/script/munin/example_simple.rb +24 -0
  72. data/generators/vulcanize/templates/munin/templates.yml +1 -0
  73. data/generators/vulcanize/templates/mysql/config/rubber/common/database.yml +11 -0
  74. data/generators/vulcanize/templates/mysql/config/rubber/deploy-mysql.rb +178 -0
  75. data/generators/vulcanize/templates/mysql/config/rubber/role/db/crontab +14 -0
  76. data/generators/vulcanize/templates/mysql/config/rubber/role/db/monit-mysql.cnf +10 -0
  77. data/generators/vulcanize/templates/mysql/config/rubber/role/db/my.cnf +167 -0
  78. data/generators/vulcanize/templates/mysql/config/rubber/role/mysql_slave/mysql_slave_munin_plugin +51 -0
  79. data/generators/vulcanize/templates/mysql/config/rubber/rubber-mysql.yml +38 -0
  80. data/generators/vulcanize/templates/mysql/templates.yml +1 -0
  81. data/generators/vulcanize/templates/mysql_cluster/config/rubber/common/mysql_cluster_migrations.rb +13 -0
  82. data/generators/vulcanize/templates/mysql_cluster/config/rubber/deploy-mysql_cluster.rb +173 -0
  83. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_data/my.cnf +15 -0
  84. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_mgm/ndb_mgmd.cnf +39 -0
  85. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_sql/monit-mysql_cluster_sql.cnf +10 -0
  86. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_sql/my.cnf +23 -0
  87. data/generators/vulcanize/templates/mysql_cluster/config/rubber/rubber-mysql_cluster.yml +32 -0
  88. data/generators/vulcanize/templates/mysql_cluster/templates.yml +1 -0
  89. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/database.yml +16 -0
  90. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/monit-mysql_proxy.cnf +10 -0
  91. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy +153 -0
  92. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy.conf +10 -0
  93. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy.lua +5 -0
  94. data/generators/vulcanize/templates/mysql_proxy/config/rubber/deploy-mysql_proxy.rb +52 -0
  95. data/generators/vulcanize/templates/mysql_proxy/config/rubber/rubber-mysql_proxy.yml +11 -0
  96. data/generators/vulcanize/templates/mysql_proxy/templates.yml +1 -0
  97. data/generators/vulcanize/templates/nginx/config/rubber/deploy-nginx.rb +45 -0
  98. data/generators/vulcanize/templates/nginx/config/rubber/role/web/crontab +9 -0
  99. data/generators/vulcanize/templates/nginx/config/rubber/role/web/monit-nginx.conf +9 -0
  100. data/generators/vulcanize/templates/nginx/config/rubber/role/web/nginx.conf +133 -0
  101. data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/index.html +23 -0
  102. data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/nginx-tools.conf +74 -0
  103. data/generators/vulcanize/templates/nginx/config/rubber/rubber-nginx.yml +33 -0
  104. data/generators/vulcanize/templates/nginx/templates.yml +1 -0
  105. data/generators/vulcanize/templates/passenger/config/rubber/deploy-passenger.rb +27 -0
  106. data/generators/vulcanize/templates/passenger/config/rubber/role/web/passenger.conf +8 -0
  107. data/generators/vulcanize/templates/passenger/config/rubber/rubber-passenger.yml +4 -0
  108. data/generators/vulcanize/templates/passenger/templates.yml +1 -0
  109. data/generators/vulcanize/templates/sphinx/config/rubber/common/sphinx.yml +46 -0
  110. data/generators/vulcanize/templates/sphinx/config/rubber/deploy-sphinx.rb +112 -0
  111. data/generators/vulcanize/templates/sphinx/config/rubber/role/sphinx/crontab +11 -0
  112. data/generators/vulcanize/templates/sphinx/config/rubber/role/sphinx/monit-sphinx.conf +10 -0
  113. data/generators/vulcanize/templates/sphinx/config/rubber/rubber-sphinx.yml +6 -0
  114. data/generators/vulcanize/templates/sphinx/templates.yml +1 -0
  115. data/generators/vulcanize/vulcanize_generator.rb +67 -0
  116. data/lib/capistrano/hostcmd.rb +12 -0
  117. data/lib/rubber.rb +37 -0
  118. data/lib/rubber/capistrano.rb +1 -0
  119. data/lib/rubber/cloud.rb +13 -0
  120. data/lib/rubber/cloud/aws.rb +261 -0
  121. data/lib/rubber/cloud/base.rb +16 -0
  122. data/lib/rubber/configuration.rb +47 -0
  123. data/lib/rubber/dns.rb +13 -0
  124. data/lib/rubber/dns/base.rb +69 -0
  125. data/lib/rubber/dns/dyndns.rb +63 -0
  126. data/lib/rubber/dns/nettica.rb +56 -0
  127. data/lib/rubber/dns/zerigo.rb +121 -0
  128. data/lib/rubber/environment.rb +161 -0
  129. data/lib/rubber/generator.rb +197 -0
  130. data/lib/rubber/instance.rb +113 -0
  131. data/lib/rubber/recipes/rubber.rb +88 -0
  132. data/lib/rubber/recipes/rubber/bundles.rb +28 -0
  133. data/lib/rubber/recipes/rubber/deploy.rb +66 -0
  134. data/lib/rubber/recipes/rubber/instances.rb +298 -0
  135. data/lib/rubber/recipes/rubber/security_groups.rb +149 -0
  136. data/lib/rubber/recipes/rubber/setup.rb +285 -0
  137. data/lib/rubber/recipes/rubber/static_ips.rb +107 -0
  138. data/lib/rubber/recipes/rubber/utils.rb +195 -0
  139. data/lib/rubber/recipes/rubber/volumes.rb +263 -0
  140. data/lib/rubber/tasks/rubber.rb +218 -0
  141. data/lib/rubber/util.rb +33 -0
  142. data/test/environment_test.rb +118 -0
  143. data/test/generator_test.rb +323 -0
  144. data/test/instance_test.rb +38 -0
  145. data/test/test_helper.rb +4 -0
  146. data/test/util_test.rb +16 -0
  147. metadata +246 -0
@@ -0,0 +1,47 @@
1
+ require 'logger'
2
+ require 'rubber/environment'
3
+ require 'rubber/instance'
4
+ require 'rubber/generator'
5
+
6
+ module Rubber
7
+ module Configuration
8
+
9
+ @@configurations = {}
10
+
11
+ def self.get_configuration(env=nil, root=nil)
12
+ key = "#{env}-#{root}"
13
+ @@configurations[key] ||= ConfigHolder.new(env, root)
14
+ end
15
+
16
+ def self.rubber_env
17
+ raise "This convenience method needs RUBBER_ENV to be set" unless RUBBER_ENV
18
+ cfg = Rubber::Configuration.get_configuration(RUBBER_ENV)
19
+ host = cfg.environment.current_host
20
+ roles = cfg.instance[host].role_names rescue nil
21
+ cfg.environment.bind(roles, host)
22
+ end
23
+
24
+ def self.rubber_instances
25
+ raise "This convenience method needs RUBBER_ENV to be set" unless RUBBER_ENV
26
+ Rubber::Configuration.get_configuration(RUBBER_ENV).instance
27
+ end
28
+
29
+ class ConfigHolder
30
+ def initialize(env=nil, root=nil)
31
+ root = "#{RUBBER_ROOT}/config/rubber" unless root
32
+ instance_cfg = "#{root}/instance" + (env ? "-#{env}.yml" : ".yml")
33
+ @environment = Environment.new("#{root}")
34
+ @instance = Instance.new(instance_cfg)
35
+ end
36
+
37
+ def environment
38
+ @environment
39
+ end
40
+
41
+ def instance
42
+ @instance
43
+ end
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,13 @@
1
+ require "rubber/dns/base.rb"
2
+
3
+ module Rubber
4
+ module Dns
5
+
6
+ def self.get_provider(provider, env)
7
+ require "rubber/cloud/#{provider}"
8
+ clazz = Rubber::Dns.const_get(provider.capitalize)
9
+ return clazz.new(env)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,69 @@
1
+ module Rubber
2
+ module Dns
3
+
4
+ class Base
5
+
6
+ attr_reader :env
7
+
8
+ def initialize(env)
9
+ @env = env
10
+ end
11
+
12
+ def update(host, ip)
13
+ if up_to_date(host, ip)
14
+ puts "IP has not changed for #{host}, not updating dynamic DNS"
15
+ else
16
+ if ! host_exists?(host)
17
+ puts "Creating dynamic DNS: #{host} => #{ip}"
18
+ create_host_record(host, ip)
19
+ else
20
+ puts "Updating dynamic DNS: #{host} => #{ip}"
21
+ update_host_record(host, ip)
22
+ end
23
+ end
24
+ end
25
+
26
+ def destroy(host)
27
+ if host_exists?(host)
28
+ puts "Destroying dynamic DNS record: #{host}"
29
+ destroy_host_record(host)
30
+ end
31
+ end
32
+
33
+ def hostname(host)
34
+ "#{host}.#{@env.domain}"
35
+ end
36
+
37
+ def up_to_date(host, ip)
38
+ # This queries dns server directly instead of using hosts file
39
+ current_ip = nil
40
+ Resolv::DNS.open(:nameserver => [nameserver], :search => [], :ndots => 1) do |dns|
41
+ current_ip = dns.getaddress(hostname(host)).to_s rescue nil
42
+ end
43
+ return ip == current_ip
44
+ end
45
+
46
+ def nameserver()
47
+ raise "nameserver not implemented"
48
+ end
49
+
50
+ def host_exists?(host)
51
+ raise "host_exists? not implemented"
52
+ end
53
+
54
+ def create_host_record(host, ip)
55
+ raise "create_host_record not implemented"
56
+ end
57
+
58
+ def destroy_host_record(host)
59
+ raise "destroy_host_record not implemented"
60
+ end
61
+
62
+ def update_host_record(host, ip)
63
+ raise "update_host_record not implemented"
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,63 @@
1
+ module Rubber
2
+ module Dns
3
+
4
+ class Dyndns < Base
5
+
6
+ def initialize(env)
7
+ super(env)
8
+ @dyndns_env = env.dns_providers.dyndns
9
+ @user, @pass = @dyndns_env.user, @dyndns_env.password
10
+ @update_url = @dyndns_env.update_url || 'https://members.dyndns.org/nic/update?hostname=%host%&myip=%ip%'
11
+ @update_url = @update_url.gsub(/%([^%]+)%/, '#{\1}')
12
+ end
13
+
14
+ def nameserver
15
+ "ns1.mydyndns.org"
16
+ end
17
+
18
+ def host_exists?(host)
19
+ begin
20
+ Resolv::DNS.open(:nameserver => [nameserver], :search => [], :ndots => 1) do |dns|
21
+ dns.getresource(hostname(host), Resolv::DNS::Resource::IN::A)
22
+ end
23
+ rescue
24
+ raise "Domain needs to exist in dyndns as an A record before record can be updated"
25
+ end
26
+ return true
27
+ end
28
+
29
+ def create_host_record(host, ip)
30
+ puts "WARNING: No create record available for dyndns, you need to do so manually"
31
+ end
32
+
33
+ def destroy_host_record(host)
34
+ puts "WARNING: No destroy record available for dyndns, you need to do so manually"
35
+ end
36
+
37
+ def update_host_record(host, ip)
38
+ host = hostname(host)
39
+ update_url = eval('%Q{' + @update_url + '}')
40
+
41
+ # This header is required by dyndns.org
42
+ headers = {
43
+ "User-Agent" => "Capistrano - Rubber - 0.1"
44
+ }
45
+
46
+ uri = URI.parse(update_url)
47
+ http = Net::HTTP.new(uri.host, uri.port)
48
+ # switch on SSL
49
+ http.use_ssl = true if uri.scheme == "https"
50
+ # suppress verification warning
51
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
52
+ req = Net::HTTP::Get.new(update_url.gsub(/.*:\/\/[^\/]*/, ''), headers)
53
+ # authentication details
54
+ req.basic_auth @user, @pass
55
+ resp = http.request(req)
56
+ # print out the response for the update
57
+ puts "DynDNS Update result: #{resp.body}"
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,56 @@
1
+ require 'nettica/client'
2
+ module Rubber
3
+ module Dns
4
+
5
+ class Nettica < Base
6
+
7
+ def initialize(env)
8
+ super(env)
9
+ @nettica_env = @env.dns_providers.nettica
10
+ @client = Nettica::Client.new(@nettica_env.user, @nettica_env.password)
11
+ @ttl = (@nettica_env.ttl || 300).to_i
12
+ @record_type = @nettica_env.record_type || "A"
13
+ end
14
+
15
+ def nameserver
16
+ "dns1.nettica.com"
17
+ end
18
+
19
+ def host_exists?(host)
20
+ domain_info = @client.list_domain(env.domain)
21
+ raise "Domain needs to exist in nettica before records can be updated" unless domain_info.record
22
+ return domain_info.record.any? { |r| r.hostName == host }
23
+ end
24
+
25
+ def create_host_record(host, ip)
26
+ new = @client.create_domain_record(env.domain, host, @record_type, ip, @ttl, 0)
27
+ @client.add_record(new)
28
+ end
29
+
30
+ def destroy_host_record(host)
31
+ old_record = @client.list_domain(env.domain).record.find {|r| r.hostName == host }
32
+ old = @client.create_domain_record(env.domain, host, old_record.recordType, old_record.data, old_record.tTL, old_record.priority)
33
+ @client.delete_record(old)
34
+ end
35
+
36
+ def update_host_record(host, ip)
37
+ old_record = @client.list_domain(env.domain).record.find {|r| r.hostName == host }
38
+ update_record(host, ip, old_record)
39
+ end
40
+
41
+ # update the top level domain record which has an empty hostName
42
+ def update_domain_record(ip)
43
+ old_record = @client.list_domain(env.domain).record.find {|r| r.hostName == '' and r.recordType == 'A' and r.data =~ /\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/}
44
+ update_record('', ip, old_record)
45
+ end
46
+
47
+ def update_record(host, ip, old_record)
48
+ old = @client.create_domain_record(env.domain, host, old_record.recordType, old_record.data, old_record.tTL, old_record.priority)
49
+ new = @client.create_domain_record(env.domain, host, @record_type, ip, @ttl, 0)
50
+ @client.update_record(old, new)
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,121 @@
1
+ require 'rubygems'
2
+ require 'httparty'
3
+
4
+ module Rubber
5
+ module Dns
6
+
7
+
8
+ class Zone
9
+ include HTTParty
10
+ format :xml
11
+
12
+ def initialize(customer_id, email, token, domain)
13
+ self.class.basic_auth email, token
14
+ self.class.base_uri "https://ns.zerigo.com/accounts/#{customer_id}"
15
+ @domain = domain
16
+ refresh()
17
+ end
18
+
19
+ def hosts
20
+ hosts = self.class.get("/zones/#{@zone['id']}/hosts.xml")
21
+ return hosts['hosts']
22
+ end
23
+
24
+ def host(hostname)
25
+ hosts = self.class.get("/zones/#{@zone['id']}/hosts.xml?fqdn=#{hostname}.#{@domain}")
26
+ return (hosts['hosts'] || []).first
27
+ end
28
+
29
+ def new_host
30
+ self.class.get("/zones/#{@zone['id']}/hosts/new.xml")['host']
31
+ end
32
+
33
+ def create_host(host)
34
+ self.class.post("/zones/#{@zone['id']}/hosts.xml", :body => {:host => host})
35
+ end
36
+
37
+ def update_host(host)
38
+ host_id = host['id']
39
+ self.class.put("/zones/#{@zone['id']}/hosts/#{host_id}.xml", :body => {:host => host})
40
+ end
41
+
42
+ def delete_host(hostname)
43
+ host_id = host(hostname)['id']
44
+ self.class.delete("/zones/#{@zone['id']}/hosts/#{host_id}.xml")
45
+ end
46
+
47
+ def refresh
48
+ zone_id = @zone['id'] rescue nil
49
+ if zone_id
50
+ @zone = self.class.get("/zones/#{zone_id}.xml")
51
+ else
52
+ zones = self.class.get('/zones.xml')
53
+ @zone = zones["zones"].find {|z| z["domain"] == @domain }
54
+ end
55
+ end
56
+
57
+ def data
58
+ return @zone
59
+ end
60
+
61
+ protected
62
+
63
+ def zones()
64
+ self.class.get('/zones.xml')
65
+ end
66
+
67
+ def zone(domain_name)
68
+ zone = zones
69
+ return zone
70
+ end
71
+
72
+ end
73
+
74
+ class Zerigo < Base
75
+
76
+ def initialize(env)
77
+ super(env)
78
+ @zerigo_env = env.dns_providers.zerigo
79
+ @ttl = (@zerigo_env.ttl || 300).to_i
80
+ @record_type = @zerigo_env.record_type || "A"
81
+ @zone = Zone.new(@zerigo_env.customer_id, @zerigo_env.email, @zerigo_env.token, env.domain)
82
+ end
83
+
84
+ def nameserver
85
+ "a.ns.zerigo.net"
86
+ end
87
+
88
+ def host_exists?(host)
89
+ @zone.host(host)
90
+ end
91
+
92
+ def create_host_record(host, ip)
93
+ host = @zone.new_host()
94
+ host['host-type'] = @record_type
95
+ host['ttl'] = @ttl
96
+ host['hostname'] = host
97
+ host['data'] = ip
98
+ @zone.create_host(host)
99
+ end
100
+
101
+ def destroy_host_record(host)
102
+ @zone.delete_host(host)
103
+ end
104
+
105
+ def update_host_record(host, ip)
106
+ old = @zone.host(host)
107
+ old['data'] = ip
108
+ @zone.update_host(old)
109
+ end
110
+
111
+ # update the top level domain record which has an empty hostName
112
+ def update_domain_record(ip)
113
+ old = @zone.hosts.find {|h| h['hostname'].nil? }
114
+ old['data'] = ip
115
+ @zone.update_host(old)
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+ end
@@ -0,0 +1,161 @@
1
+ require 'yaml'
2
+ require 'socket'
3
+ require 'delegate'
4
+
5
+ module Rubber
6
+ module Configuration
7
+ # Contains the configuration defined in rubber.yml
8
+ # Handles selecting of correct config values based on
9
+ # the host/role passed into bind
10
+ class Environment
11
+ attr_reader :config_root
12
+ attr_reader :config_files
13
+ attr_reader :config_secret
14
+
15
+ def initialize(config_root)
16
+ @config_root = config_root
17
+ @config_files = ["#{@config_root}/rubber.yml"] + Dir["#{@config_root}/rubber-*.yml"].sort
18
+ @items = {}
19
+ @config_files.each { |file| read_config(file) }
20
+ @config_secret = bind().rubber_secret
21
+ read_config(@config_secret) if @config_secret
22
+ end
23
+
24
+ def read_config(file)
25
+ LOGGER.debug{"Reading rubber configuration from #{file}"}
26
+ if File.exist?(file)
27
+ @items = Environment.combine(@items, YAML.load_file(file) || {})
28
+ end
29
+ end
30
+
31
+ def known_roles
32
+ roles_dir = File.join(@config_root, "role")
33
+ roles = Dir.entries(roles_dir)
34
+ roles.delete_if {|d| d =~ /(^\..*)/}
35
+ end
36
+
37
+ def current_host
38
+ Socket::gethostname.gsub(/\..*/, '')
39
+ end
40
+
41
+ def current_full_host
42
+ Socket::gethostname
43
+ end
44
+
45
+ def bind(roles = nil, host = nil)
46
+ BoundEnv.new(@items, roles, host)
47
+ end
48
+
49
+ # combine old and new into a single value:
50
+ # non-nil wins if other is nil
51
+ # arrays just get unioned
52
+ # hashes also get unioned, but the values of conflicting keys get combined
53
+ # All else, the new value wins
54
+ def self.combine(old, new)
55
+ return old if new.nil?
56
+ return new if old.nil?
57
+ value = old
58
+ if old.is_a?(Hash) && new.is_a?(Hash)
59
+ value = old.clone
60
+ new.each do |nk, nv|
61
+ value[nk] = combine(value[nk], nv)
62
+ end
63
+ elsif old.is_a?(Array) && new.is_a?(Array)
64
+ value = old | new
65
+ else
66
+ value = new
67
+ end
68
+ return value
69
+ end
70
+
71
+ class HashValueProxy < Hash
72
+ attr_reader :global
73
+
74
+ def initialize(global, receiver)
75
+ @global = global
76
+ super()
77
+ replace(receiver)
78
+ end
79
+
80
+ def [](name)
81
+ value = super(name)
82
+ value = global[name] if global && !value
83
+ return expand(value)
84
+ end
85
+
86
+ def each
87
+ each_key do |key|
88
+ yield key, self[key]
89
+ end
90
+ end
91
+
92
+ def method_missing(method_id)
93
+ key = method_id.id2name
94
+ return self[key]
95
+ end
96
+
97
+ def expand_string(val)
98
+ while val =~ /\#\{[^\}]+\}/
99
+ val = eval('%Q{' + val + '}', binding)
100
+ end
101
+ val = true if val =="true"
102
+ val = false if val == "false"
103
+ return val
104
+ end
105
+
106
+ def expand(value)
107
+ val = case value
108
+ when Hash
109
+ HashValueProxy.new(global || self, value)
110
+ when String
111
+ expand_string(value)
112
+ when Enumerable
113
+ value.collect {|v| expand(v) }
114
+ else
115
+ value
116
+ end
117
+ return val
118
+ end
119
+
120
+ end
121
+
122
+ class BoundEnv < HashValueProxy
123
+ attr_reader :roles
124
+ attr_reader :host
125
+ attr_reader :full_host
126
+
127
+ def initialize(global, roles, host)
128
+ @roles = roles
129
+ @host = host
130
+ bound_global = bind_config(global)
131
+ super(nil, bound_global)
132
+ @full_host = "#{host}.#{domain}" rescue nil
133
+ end
134
+
135
+ # Forces role/host overrides into config
136
+ def bind_config(global)
137
+ global = global.clone()
138
+ role_overrides = global.delete("roles") || {}
139
+ host_overrides = global.delete("hosts") || {}
140
+ roles.to_a.each do |role|
141
+ role_overrides[role].each do |k, v|
142
+ global[k] = Environment.combine(global[k], v)
143
+ end if role_overrides[role]
144
+ end
145
+ host_overrides[host].each do |k, v|
146
+ global[k] = Environment.combine(global[k], v)
147
+ end if host_overrides[host]
148
+ return global
149
+ end
150
+
151
+ def method_missing(method_id)
152
+ key = method_id.id2name
153
+ return self[key]
154
+ end
155
+
156
+ end
157
+
158
+ end
159
+
160
+ end
161
+ end