devdnsd 2.4.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.rbx/8b/8b2d1928657c1eeac610d1207ff1bee6e918287c +857 -0
  3. data/.rbx/db/dbd6130694811dcd0359863bd5380c673db0fe71 +288 -0
  4. data/.travis-gemfile +1 -2
  5. data/.travis.yml +1 -0
  6. data/Gemfile +2 -3
  7. data/README.md +3 -1
  8. data/Rakefile +1 -1
  9. data/bin/devdnsd +29 -5
  10. data/config/devdnsd_config.sample +2 -5
  11. data/devdnsd.gemspec +6 -5
  12. data/doc/DevDNSd.html +4 -4
  13. data/doc/DevDNSd/Application.html +560 -520
  14. data/doc/DevDNSd/ApplicationMethods.html +4 -4
  15. data/doc/DevDNSd/ApplicationMethods/Aliases.html +780 -0
  16. data/doc/DevDNSd/ApplicationMethods/Server.html +46 -46
  17. data/doc/DevDNSd/ApplicationMethods/System.html +222 -20
  18. data/doc/DevDNSd/ApplicationMethods/System/ClassMethods.html +3 -3
  19. data/doc/DevDNSd/Configuration.html +20 -20
  20. data/doc/DevDNSd/Errors.html +3 -3
  21. data/doc/DevDNSd/Errors/InvalidRule.html +3 -3
  22. data/doc/DevDNSd/Rule.html +15 -15
  23. data/doc/DevDNSd/Version.html +5 -5
  24. data/doc/_index.html +11 -4
  25. data/doc/class_list.html +1 -1
  26. data/doc/file.README.html +6 -4
  27. data/doc/frames.html +1 -1
  28. data/doc/index.html +6 -4
  29. data/doc/method_list.html +73 -31
  30. data/doc/top-level-namespace.html +3 -3
  31. data/lib/devdnsd.rb +6 -3
  32. data/lib/devdnsd/application.rb +220 -11
  33. data/lib/devdnsd/configuration.rb +19 -1
  34. data/lib/devdnsd/errors.rb +1 -1
  35. data/lib/devdnsd/rule.rb +2 -2
  36. data/lib/devdnsd/version.rb +3 -3
  37. data/locales/en.yml +28 -2
  38. data/locales/it.yml +29 -2
  39. data/spec/coverage_helper.rb +3 -3
  40. data/spec/devdnsd/application_spec.rb +202 -51
  41. data/spec/devdnsd/configuration_spec.rb +1 -1
  42. data/spec/devdnsd/rule_spec.rb +1 -1
  43. data/spec/resolver_helper.rb +51 -0
  44. data/spec/spec_helper.rb +3 -5
  45. metadata +34 -26
@@ -6,7 +6,7 @@
6
6
  <title>
7
7
  Top Level Namespace
8
8
 
9
- &mdash; Documentation by YARD 0.8.6.2
9
+ &mdash; Documentation by YARD 0.8.7
10
10
 
11
11
  </title>
12
12
 
@@ -103,9 +103,9 @@
103
103
  </div>
104
104
 
105
105
  <div id="footer">
106
- Generated on Sat Jul 20 13:46:44 2013 by
106
+ Generated on Sun Aug 18 16:18:38 2013 by
107
107
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
108
- 0.8.6.2 (ruby-1.9.3).
108
+ 0.8.7 (ruby-2.0.0).
109
109
  </div>
110
110
 
111
111
  </body>
data/lib/devdnsd.rb CHANGED
@@ -1,13 +1,16 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@cowtech.it>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
7
7
  require "rubygems"
8
- require "mamertes"
8
+ require "bovem"
9
9
  require "rubydns"
10
10
  require "rexec/daemon"
11
+ require "mustache"
12
+ require "ipaddr"
13
+ require "fiber"
11
14
 
12
15
  Lazier.load!(:object)
13
16
 
@@ -17,5 +20,5 @@ require "devdnsd/errors"
17
20
  require "devdnsd/rule"
18
21
  require "devdnsd/version" if !defined?(DevDNSd::Version)
19
22
 
20
- # DevDNSd is only supported on MRI
23
+ # DevDNSd is not supported on JRuby
21
24
  DevDNSd::Application.check_ruby_implementation
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@cowtech.it>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
@@ -87,6 +87,8 @@ module DevDNSd
87
87
  if !Process.respond_to?(:fork) then
88
88
  logger.warn(i18n.no_fork)
89
89
  @config.foreground = true
90
+ elsif @command.options[:foreground].value then
91
+ @config.foreground = true
90
92
  end
91
93
 
92
94
  @config.foreground ? perform_server : RExec::Daemon::Controller.start(self.class)
@@ -101,6 +103,23 @@ module DevDNSd
101
103
  true
102
104
  end
103
105
 
106
+ # Adds aliases to an interface.
107
+ #
108
+ # @param options [Hash] The options provided by the user.
109
+ # @return [Boolean] `true` if action succeeded, `false` otherwise.
110
+ def action_add(options)
111
+ manage_aliases(:add, i18n.add_empty, options)
112
+ end
113
+
114
+ # Removes aliases from an interface.
115
+ #
116
+ # @param options [Hash] The options provided by the user.
117
+ # @return [Boolean] `true` if action succeeded, `false` otherwise.
118
+ def action_remove(options)
119
+ manage_aliases(:remove, i18n.remove_empty, options)
120
+ end
121
+
122
+
104
123
  # Installs the application into the autolaunch.
105
124
  #
106
125
  # @return [Boolean] `true` if action succeeded, `false` otherwise.
@@ -267,6 +286,183 @@ module DevDNSd
267
286
  end
268
287
  end
269
288
 
289
+ # Methods to handle interfaces aliases.
290
+ module Aliases
291
+ extend ActiveSupport::Concern
292
+
293
+ # Manages aliases.
294
+ #
295
+ # @param operation [Symbol] The type of operation. Can be `:add` or `:remove`.
296
+ # @param message [String] The message to show if no addresses are found.
297
+ # @param options [Hash] The options provided by the user.
298
+ # @return [Boolean] `true` if operation succeeded, `false` otherwise.
299
+ def manage_aliases(operation, message, options)
300
+ config = self.config
301
+ options.each { |k, v| config.send("#{k}=", v) if config.respond_to?("#{k}=") }
302
+
303
+ addresses = compute_addresses
304
+
305
+ if addresses.present? then
306
+ # Now, for every address, call the command
307
+ addresses.all? {|address| manage_address(operation, address, options[:dry_run]) }
308
+ else
309
+ @logger.error(message)
310
+ false
311
+ end
312
+ end
313
+
314
+ # Adds or removes an alias from the interface.
315
+ #
316
+ # @param type [Symbol] The operation to execute. Can be `:add` or `:remove`.
317
+ # @param address [String] The address to manage.
318
+ # @param dry_run [Boolean] If only show which modifications will be done.
319
+ # @return [Boolean] `true` if operation succeeded, `false` otherwise.
320
+ def manage_address(type, address, dry_run = false)
321
+ locale = i18n
322
+ rv, command, prefix = setup_management(type, address)
323
+
324
+ # Now execute
325
+ if rv then
326
+ if !dry_run then
327
+ execute_manage(command, prefix, type, address, self.config)
328
+ else
329
+ log_management(:dry_run, prefix, type, locale.remove, locale.add, address, config)
330
+ end
331
+ end
332
+
333
+ rv
334
+ end
335
+
336
+ # Computes the list of address to manage.
337
+ #
338
+ # @param type [Symbol] The type of addresses to consider. Valid values are `:ipv4`, `:ipv6`, otherwise all addresses are considered.
339
+ # @return [Array] The list of addresses to add or remove from the interface.
340
+ def compute_addresses(type = :all)
341
+ config = self.config
342
+ config.addresses.present? ? filter_addresses(config, type) : generate_addresses(config, type)
343
+ end
344
+
345
+ # Checks if an address is a valid IPv4 address.
346
+ #
347
+ # @param address [String] The address to check.
348
+ # @return [Boolean] `true` if the address is a valid IPv4 address, `false` otherwise.
349
+ def is_ipv4?(address)
350
+ address = address.ensure_string
351
+
352
+ mo = /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/.match(address)
353
+ (mo && mo.captures.all? {|i| i.to_i < 256}) ? true : false
354
+ end
355
+
356
+ # Checks if an address is a valid IPv6 address.
357
+ #
358
+ # @param address [String] The address to check.
359
+ # @return [Boolean] `true` if the address is a valid IPv6 address, `false` otherwise.
360
+ def is_ipv6?(address)
361
+ address = address.ensure_string
362
+
363
+ catch(:valid) do
364
+ # IPv6 (normal)
365
+ throw(:valid, true) if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*\Z/ =~ address
366
+ throw(:valid, true) if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ address
367
+ throw(:valid, true) if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ address
368
+ # IPv6 (IPv4 compat)
369
+ throw(:valid, true) if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:/ =~ address && is_ipv4?($')
370
+ throw(:valid, true) if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ address && is_ipv4?($')
371
+ throw(:valid, true) if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ address && is_ipv4?($')
372
+
373
+ false
374
+ end
375
+ end
376
+
377
+ private
378
+ # Setups management.
379
+ #
380
+ # @param type [Symbol] The type of operation. Can be `:add` or `:remove`.
381
+ # @param address [String] The address to manage.
382
+ # @return [Array] A list of parameters for the management.
383
+ def setup_management(type, address)
384
+ begin
385
+ @addresses ||= compute_addresses
386
+ length = @addresses.length
387
+ length_s = length.to_s.length
388
+ [true, build_command(type, address), "{mark=blue}[{mark=bright white}#{((@addresses.index(address) || 0) + 1).indexize(length_s)}{mark=reset blue}/{/mark}#{length}{/mark}]{/mark}"]
389
+ rescue ArgumentError
390
+ [false]
391
+ end
392
+ end
393
+
394
+ # Filters a list of addresses to return just certain type(s).
395
+ #
396
+ # @param config [Configuration] The current configuration.
397
+ # @param type [Symbol] The type of addresses to return.
398
+ # @return [Array] A list of IPs.
399
+ def filter_addresses(config, type)
400
+ filters = [:ipv4, :ipv6].select {|i| type == i || type == :all }.compact
401
+ config.addresses.select { |address| filters.any? {|filter| send("is_#{filter}?", address) } }.compact.uniq
402
+ end
403
+
404
+ # Generates a list of addresses which are immediate successors of a start address.
405
+ #
406
+ # @param config [Configuration] The current configuration.
407
+ # @param type [Symbol] The type of addresses to return.
408
+ # @return [Array] A list of IPs.
409
+ def generate_addresses(config, type)
410
+ begin
411
+ ip = IPAddr.new(config.start_address.ensure_string)
412
+ raise ArgumentError if type != :all && !ip.send("#{type}?")
413
+
414
+ [config.aliases, 1].max.times.collect {|_|
415
+ current = ip
416
+ ip = ip.succ
417
+ current
418
+ }
419
+ rescue ArgumentError
420
+ []
421
+ end
422
+ end
423
+
424
+ # Builds the command to execute.
425
+ #
426
+ # @param type [Symbol] The type of operation. Can be `:add` or `:remove`.
427
+ # @param address [String] The address to manage.
428
+ # @return [String] The command to execute.
429
+ def build_command(type, address)
430
+ Mustache.render(config.send((type == :remove) ? :remove_command : :add_command), {interface: config.interface, address: address.to_s}) + " > /dev/null 2>&1"
431
+ end
432
+
433
+ # Executes management.
434
+ #
435
+ # @param command [String] The command to execute.
436
+ # @param prefix [String] The prefix to apply to the message.
437
+ # @param type [Symbol] The type of operation. Can be `:add` or `:remove`.
438
+ # @param address [String] The address that will be managed.
439
+ # @param config [Configuration] The current configuration.
440
+ # @return [Boolean] `true` if operation succeeded, `false` otherwise.
441
+ def execute_manage(command, prefix, type, address, config)
442
+ locale = i18n
443
+ log_management(:run, prefix, type, locale.removing, locale.adding, address, config)
444
+ rv = execute_command(command)
445
+ labels = (type == :remove ? [locale.remove, locale.from] : [locale.add, locale.to])
446
+ @logger.error(@command.application.console.replace_markers(locale.general_error(labels[0], address, labels[1], config.interface))) if !rv
447
+ rv
448
+ end
449
+
450
+ # Logs an operation.
451
+ #
452
+ # @param message [Symbol] The message to print.
453
+ # @param prefix [String] The prefix to apply to the message.
454
+ # @param type [Symbol] The type of operation. Can be `:add` or `:remove`.
455
+ # @param remove_label [String] The label to use for removing.
456
+ # @param add_label [String] The label to use for adding.
457
+ # @param address [String] The address that will be managed.
458
+ # @param config [Configuration] The current configuration.
459
+ def log_management(message, prefix, type, remove_label, add_label, address, config)
460
+ locale = i18n
461
+ labels = (type == :remove ? [remove_label, locale.from] : [add_label, locale.to])
462
+ @logger.info(@command.application.console.replace_markers(i18n.send(message, prefix, labels[0], address, labels[1], config.interface)))
463
+ end
464
+ end
465
+
270
466
  # Methods to process requests.
271
467
  module Server
272
468
  # Starts the DNS server.
@@ -337,7 +533,7 @@ module DevDNSd
337
533
  def perform_process_rule(rule, type, match_data, transaction)
338
534
  type = DevDNSd::Rule.resource_class_to_symbol(type)
339
535
  reply = !rule.block.nil? ? rule.block.call(match_data, type, transaction) : rule.reply
340
- reply = match_data[0].gsub(rule.match, reply.gsub("$", "\\")) if rule.match.is_a?(::Regexp) && reply && match_data[0]
536
+ reply = match_data[0].gsub(rule.match, reply.gsub("$", "\\")) if rule.match.is_a?(::Regexp) && reply && match_data && match_data[0]
341
537
 
342
538
  logger.debug(i18n.match(rule.match, type))
343
539
  [reply, type]
@@ -350,11 +546,21 @@ module DevDNSd
350
546
  # @param type [Symbol] The type of query.
351
547
  def finalize_reply(reply, rule, type)
352
548
  rv = []
353
- rv << rule.options.delete(:preference).to_integer(10) if type == :MX
549
+ rv << rule.options.delete(:priority).to_integer(10) if type == :MX
354
550
  rv << ([:A, :AAAA].include?(type) ? reply : Resolv::DNS::Name.create(reply))
355
- rv << rule.options.merge({resource_class: DevDNSd::Rule.symbol_to_resource_class(type, @locale)})
551
+ rv << rule.options.merge({resource_class: DevDNSd::Rule.symbol_to_resource_class(type, @locale), ttl: validate_ttl(rule.options.delete(:ttl))})
356
552
  rv
357
553
  end
554
+
555
+ # Validates a TTL.
556
+ #
557
+ # @param current [Fixnum] The current value.
558
+ # @param default [Fixnum] The value to return if current is not valid.
559
+ # @return [Fixnum] The validated TTL.
560
+ def validate_ttl(current, default = 300)
561
+ current = current.to_integer
562
+ current > 0 ? current : default
563
+ end
358
564
  end
359
565
  end
360
566
 
@@ -363,7 +569,7 @@ module DevDNSd
363
569
  # @attribute [r] config
364
570
  # @return [Configuration] The {Configuration Configuration} of this application.
365
571
  # @attribute [r] command
366
- # @return [Mamertes::Command] The Mamertes command.
572
+ # @return [Bovem::Command] The Bovem command.
367
573
  # @attribute logger
368
574
  # @return [Bovem::Logger] The logger for this application.
369
575
  # @attribute [r] locale
@@ -377,6 +583,7 @@ module DevDNSd
377
583
 
378
584
  include Lazier::I18n
379
585
  include DevDNSd::ApplicationMethods::System
586
+ include DevDNSd::ApplicationMethods::Aliases
380
587
  include DevDNSd::ApplicationMethods::Server
381
588
 
382
589
  attr_reader :config
@@ -386,7 +593,7 @@ module DevDNSd
386
593
 
387
594
  # Creates a new application.
388
595
  #
389
- # @param command [Mamertes::Command] The current Mamertes command.
596
+ # @param command [Bovem::Command] The current Bovem command.
390
597
  # @param locale [Symbol] The locale to use for the application.
391
598
  def initialize(command, locale)
392
599
  i18n_setup(:devdnsd, ::File.absolute_path(::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/"))
@@ -397,7 +604,6 @@ module DevDNSd
397
604
  options = @command.application.get_options.reject {|_, v| v.nil? }
398
605
 
399
606
  # Setup logger
400
- Bovem::Logger.start_time = Time.now
401
607
  @logger = Bovem::Logger.create(Bovem::Logger.get_real_file(options["log_file"]) || Bovem::Logger.default_file, Logger::INFO)
402
608
 
403
609
  # Open configuration
@@ -427,7 +633,7 @@ module DevDNSd
427
633
 
428
634
  # Returns a unique (singleton) instance of the application.
429
635
  #
430
- # @param command [Mamertes::Command] The current Mamertes command.
636
+ # @param command [Bovem::Command] The current Bovem command.
431
637
  # @param locale [Symbol] The locale to use for the application.
432
638
  # @param force [Boolean] If to force recreation of the instance.
433
639
  # @return [Application] The unique (singleton) instance of the application.
@@ -446,13 +652,16 @@ module DevDNSd
446
652
 
447
653
  # Stops the application.
448
654
  def self.quit
449
- ::EventMachine.stop rescue nil
655
+ begin
656
+ EM.add_timer(0.1) { ::EM.stop }
657
+ rescue
658
+ end
450
659
  end
451
660
 
452
661
  # Check if the current implementation supports DevDNSd.
453
662
  def self.check_ruby_implementation
454
- if defined?(Rubinius) || defined?(JRuby) then
455
- Kernel.puts(Lazier::Localizer.new(:devdnsd, ::File.absolute_path(::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/")).i18n.no_jruby_rubinius)
663
+ if defined?(JRuby) then
664
+ Kernel.puts(Lazier::Localizer.new(:devdnsd, ::File.absolute_path(::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/")).i18n.no_jruby)
456
665
  Kernel.exit(0)
457
666
  end
458
667
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@cowtech.it>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
@@ -31,6 +31,24 @@ module DevDNSd
31
31
  # The rules of the server. By default, every hostname is resolved with `127.0.0.1`.
32
32
  property :rules, default: []
33
33
 
34
+ # The default interface to manage for aliases. Default: `lo0`.
35
+ property :interface, default: "lo0"
36
+
37
+ # The default list of aliases to add. Default: `[]`.
38
+ property :addresses, default: []
39
+
40
+ # The starting address for sequential aliases. Default: `10.0.0.1`.
41
+ property :start_address, default: "10.0.0.1"
42
+
43
+ # The number of aliases to add. Default: `5`.
44
+ property :aliases, default: 5
45
+
46
+ # The command to run for adding an alias. Default: `sudo ifconfig {{interface}} alias {{address}}`.
47
+ property :add_command, default: "sudo ifconfig {{interface}} alias {{address}}"
48
+
49
+ # The command to run for removing an alias. Default: `sudo ifconfig {{interface}} alias {{address}}`.
50
+ property :remove_command, default: "sudo ifconfig {{interface}} -alias {{address}}"
51
+
34
52
  # Creates a new configuration.
35
53
  # A configuration file is a plain Ruby file with a top-level {Configuration config} object.
36
54
  #
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@cowtech.it>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
data/lib/devdnsd/rule.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@cowtech.it>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
@@ -14,7 +14,7 @@ module DevDNSd
14
14
  # @attribute reply
15
15
  # @return [String] The IP or hostname to reply back to the client. Default: `127.0.0.1`. @see .create
16
16
  # @attribute options
17
- # @return [Hash] A list of options for the request. Default is an empty hash.
17
+ # @return [Hash] A list of options for the request. Default is an empty hash. Supported key are `:priority` and `:ttl`, both integers
18
18
  # @attribute block
19
19
  # @return [Proc] An optional block to compute the reply instead of using the `reply` parameter. @see .create
20
20
  class Rule
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@cowtech.it>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
@@ -10,10 +10,10 @@ module DevDNSd
10
10
  # @see http://semver.org
11
11
  module Version
12
12
  # The major version.
13
- MAJOR = 2
13
+ MAJOR = 3
14
14
 
15
15
  # The minor version.
16
- MINOR = 4
16
+ MINOR = 0
17
17
 
18
18
  # The patch version.
19
19
  PATCH = 0
data/locales/en.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
3
+ # This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun_panda@cowtech.it>.
4
4
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
5
  #
6
6
 
@@ -10,7 +10,7 @@
10
10
  rule_invalid_options: "You can only use hashs for options."
11
11
  rule_invalid_resource: "Invalid resource class %1."
12
12
  dns_update: "Flushing DNS cache and resolvers ..."
13
- no_jruby_rubinius: "DevDNSd is not available on JRuby or Rubinius."
13
+ no_jruby: "DevDNSd is not available on JRuby."
14
14
  no_fork: "Forking is not available for this platform. Running in foreground ..."
15
15
  starting: "Starting DevDNSd ..."
16
16
  match: "Found match on %1 with type %2."
@@ -38,11 +38,37 @@
38
38
  application_help_log_file: "The log file to use. Not used if run in foreground. Default is \"/var/log/devdnsd.log\"."
39
39
  application_help_log_level: "The log level to use. Valid values are from 0 to 5 where 0 means \"all messages\". Default is 1."
40
40
  application_help_foreground: "Do not daemonize."
41
+ application_help_interface: "The interface to manage. Default is \"lo0\"."
42
+ application_help_addresses: "The list of aliases to add. Overrides sequential list."
43
+ application_help_start_address: "The starting address for sequential aliases. Default is \"10.0.0.1\"."
44
+ application_help_aliases: "The number of aliases to add. Default is 5."
45
+ application_help_add_command: "The command to run for adding an alias. Default is \"sudo ifconfig {{interface}} alias {{address}}\"."
46
+ application_help_remove_command: "The command to run for removing an alias. Default is \"sudo ifconfig {{interface}} -alias {{address}}\"."
47
+ application_help_dry_run: "Only show which modifications will be done."
41
48
  application_meta_file: "FILE"
42
49
  application_meta_domain: "DOMAIN"
43
50
  application_meta_level: "LEVEL"
44
51
  application_meta_port: "PORT"
52
+ application_meta_interface: "INTERFACE"
53
+ application_meta_address: "ADDRESS"
54
+ application_meta_addresses: "ADDRESSES"
55
+ application_meta_aliases: "ALIASES"
56
+ application_meta_command: "COMMAND"
45
57
  command_start: "Starts the server."
46
58
  command_install: "Installs the server."
47
59
  command_uninstall: "Uninstalls the server."
48
60
  command_stop: "Stops the server."
61
+ command_aliases: "Adds or removes aliases to network interfaces."
62
+ command_add: "Adds aliases."
63
+ command_remove: "Removes aliases."
64
+ removing: "Removing"
65
+ adding: "Adding"
66
+ remove: "remove"
67
+ add: "add"
68
+ to: "to "
69
+ from: "from "
70
+ general_error: "Cannot {mark=bright}%1{/mark} address {mark=bright}%2{/mark} %3interface {mark=bright}%4{/mark}."
71
+ add_empty: "No valid addresses to add to the interface found."
72
+ remove_empty: "No valid addresses to remove from the interface found."
73
+ run: "%1 {mark=bright}%2{/mark} address {mark=bright}%3{/mark} %4interface {mark=bright}%5{/mark}..."
74
+ dry_run: "%1 I will {mark=bright}%2{/mark} address {mark=bright}%3{/mark} %4interface {mark=bright}%5{/mark}..."