aboutsummaryrefslogtreecommitdiff
path: root/lib/leap_cli/commands/compile.rb
blob: 0fc95ca249ef3d6f90a8f72e6608aba0e628f35c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
module LeapCli
  module Commands

    desc "Compile generated files."
    command :compile do |c|
      c.desc 'Compiles node configuration files into hiera files used for deployment.'
      c.command :all do |all|
        all.action do |global_options,options,args|
          compile_hiera_files
        end
      end

      c.desc "Compile a DNS zone file for your provider."
      c.command :zone do |zone|
        zone.action do |global_options, options, args|
          compile_zone_file
        end
      end

      c.default_command :all
    end

    protected

    def compile_hiera_files(nodes=nil)
      # these must come first
      update_compiled_ssh_configs

      # export generated files
      manager.export_nodes(nodes)
      manager.export_secrets(nodes.nil?) # only do a "clean" export if we are examining all the nodes
    end

    def update_compiled_ssh_configs
      update_authorized_keys
      update_known_hosts
    end

    ##
    ## ZONE FILE
    ##

    def relative_hostname(fqdn)
      @domain_regexp ||= /\.?#{Regexp.escape(provider.domain)}$/
      fqdn.sub(@domain_regexp, '')
    end

    #
    # serial is any number less than 2^32 (4294967296)
    #
    def compile_zone_file
      f = $stdout

      f.puts ZONE_HEADER % [provider.domain, provider.domain, provider.domain]

      max_width = manager.nodes.values.inject(0) {|max, node| [max, relative_hostname(node.domain.full).length].max }
      put_line = lambda {|host, line| f.puts("%-#{max_width}s %s" % [host, line])}

      if provider['dns'] && provider.dns['nameservers']
        provider.dns.nameservers.each do |ns|
          put_line.call "", "IN NS #{ns}."
        end
      end

      manager.environments.each do |env|
        next if env == 'local'
        nodes = manager.nodes[:environment => env]
        next unless nodes.any?
        f.puts ENV_HEADER % (env.nil? ? 'default' : env)
        nodes.each_node do |node|
          if node.dns.public
            hostname = relative_hostname(node.domain.full)
            put_line.call relative_hostname(node.domain.full), "IN A      #{node.ip_address}"
          end
          if node['dns']['aliases']
            node['dns']['aliases'].each do |host_alias|
              if host_alias != node.domain.full
                put_line.call relative_hostname(host_alias), "IN CNAME  #{relative_hostname(node.domain.full)}"
              end
            end
          end
          if node.services.include? 'mx'
            put_line.call relative_hostname(node.domain.full_suffix), "IN MX 10  #{relative_hostname(node.domain.full)}"
          end
        end
      end
    end

    ENV_HEADER = %[
;;
;; ENVIRONMENT %s
;;

]

    ZONE_HEADER = %[
;;
;; BIND data file for %s
;;

$TTL 600

@ IN SOA %s. %s. (
  0000          ; serial
  7200          ; refresh (  24 hours)
  3600          ; retry   (   2 hours)
  1209600       ; expire  (1000 hours)
  600 )         ; minimum (   2 days)
;
]

  end
end