Class: Cloudflare::DNS::Update::Command::Top

Inherits:
Samovar::Command
  • Object
show all
Defined in:
lib/cloudflare/dns/update/command.rb

Overview

The top level utopia command.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#connectionObject

Returns the value of attribute connection.



59
60
61
# File 'lib/cloudflare/dns/update/command.rb', line 59

def connection
  @connection
end

Instance Method Details

#callObject



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/cloudflare/dns/update/command.rb', line 164

def call
  if @options[:version]
    puts VERSION
  elsif @options[:help]
    print_usage
  else
    Sync do
      connect! do
        initialize_zone
        initialize_domains
        initialize_command
        
        update_domains
      end
    end
  end
end

#configuration_storeObject



55
56
57
# File 'lib/cloudflare/dns/update/command.rb', line 55

def configuration_store
  @store ||= YAML::Store.new(@options[:configuration])
end

#connect!Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/cloudflare/dns/update/command.rb', line 61

def connect!
  configuration_store.transaction do |configuration|
    unless configuration[:token]
      prompt.puts "This configuration does not contain authorization token, we require some details."
      configuration[:token] = prompt.mask("Cloudflare token:")
    end
    
    @connection = Cloudflare.connect(token: configuration[:token])
  end
  
  return @connection unless block_given?
  
  begin
    yield @connection
  rescue Interrupt
    # Exit gracefully
  ensure
    @connection.close
  end
end

#initialize_commandObject



109
110
111
112
113
114
115
# File 'lib/cloudflare/dns/update/command.rb', line 109

def initialize_command
  configuration_store.transaction do |configuration|
    unless configuration[:content_command]
      configuration[:content_command] = prompt.ask("What command to get content for record?", default: 'curl -s ipinfo.io/ip')
    end
  end
end

#initialize_domainsObject



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/cloudflare/dns/update/command.rb', line 92

def initialize_domains
  configuration_store.transaction do |configuration|
    domains = configuration[:domains]
    
    while domains.nil? || domains.empty?
      prompt.puts "Getting list of domains for #{configuration[:zone][:name]}..."
      
      zone_id = configuration[:zone][:id]
      zone = @connection.zones.find_by_id(zone_id)
      
      dns_records = prompt.multi_select("What records do you want to update (select 1 or more)?", zone.dns_records)
      
      domains = configuration[:domains] = dns_records.map(&:value)
    end
  end
end

#initialize_zoneObject



82
83
84
85
86
87
88
89
90
# File 'lib/cloudflare/dns/update/command.rb', line 82

def initialize_zone
  configuration_store.transaction do |configuration|
    unless configuration[:zone]
      zone = prompt.select("What zone do you want to update?", @connection.zones)
      
      configuration[:zone] = zone.value
    end
  end
end

#loggerObject



47
48
49
# File 'lib/cloudflare/dns/update/command.rb', line 47

def logger
  @logger ||= Async.logger
end

#promptObject



51
52
53
# File 'lib/cloudflare/dns/update/command.rb', line 51

def prompt
  @prompt ||= TTY::Prompt.new
end

#update_domain(zone, record, content) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/cloudflare/dns/update/command.rb', line 117

def update_domain(zone, record, content)
  if content != record[:content] || @options[:force]
    logger.info "Content changed #{content.inspect}, updating records..."
    
    domain = zone.dns_records.find_by_id(record[:id])
      
    begin
      domain.update_content(content)
      
      logger.info "Updated domain: #{record[:name]} #{record[:type]} #{content}"
      record[:content] = content
    rescue => error
      logger.warn("Failed to update domain: #{record[:name]} #{record[:type]} #{content}") {error}
    end
  else
    logger.debug "Content hasn't changed: #{record[:name]} #{record[:type]} #{content}"
  end
end

#update_domains(content = nil) ⇒ Object



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/cloudflare/dns/update/command.rb', line 136

def update_domains(content = nil)
  configuration_store.transaction do |configuration|
    unless content
      logger.debug "Executing content command: #{configuration[:content_command]}"
      content, status = Open3.capture2(configuration[:content_command])
      
      unless status.success?
        raise RuntimeError.new("Content command failed with non-zero output: #{status}")
      end
      
      # Make sure there is no trailing space:
      content.chomp!
      
      configuration[:content] = content
    end
    
    unless zone = @connection.zones.find_by_id(configuration[:zone][:id])
      raise RuntimeError.new("Couldn't load zone #{configuration[:zone].inspect} from API!")
    end
    
    configuration[:domains].each do |record|
      update_domain(zone, record, content)
    end
  end
  
  return content
end