ganddyn 0.0.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.
- checksums.yaml +7 -0
 - data/.gitignore +17 -0
 - data/.rspec +2 -0
 - data/.travis.yml +8 -0
 - data/Gemfile +4 -0
 - data/LICENSE.txt +22 -0
 - data/README.md +37 -0
 - data/Rakefile +5 -0
 - data/bin/ganddyn +17 -0
 - data/ganddyn.gemspec +32 -0
 - data/lib/ganddyn/client.rb +297 -0
 - data/lib/ganddyn/ipresolver.rb +44 -0
 - data/lib/ganddyn/version.rb +3 -0
 - data/lib/ganddyn.rb +5 -0
 - data/spec/lib/ganddyn/client_spec.rb +559 -0
 - data/spec/lib/ganddyn/ipresolver_spec.rb +81 -0
 - data/spec/spec_helper.rb +35 -0
 - metadata +166 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: b0feada86e7855617874d6d329144969022a4c9c
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 7191df63d2bea9643bc2ccdf768d2a72fc9dcc91
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 116d9fe483f702b7c70e690be5801ee37dd821b4008663cc2d8cb79991d62d71dba3dedd4d5ee1f93735ab5740c7d6d59b984d91b34343208ea90fc45de4b6d7
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 66a5d1db13fe7dd1c29bdcee78fd03f3139f3c65065e1405e5bc560c7f0f6f6a3632db5217cefd6496f07e79e7cb22b9686c0da3839b5450330e79cffd99564a
         
     | 
    
        data/.gitignore
    ADDED
    
    
    
        data/.rspec
    ADDED
    
    
    
        data/.travis.yml
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE.txt
    ADDED
    
    | 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2014 Guillaume Virlet
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            MIT License
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 6 
     | 
    
         
            +
            a copy of this software and associated documentation files (the
         
     | 
| 
      
 7 
     | 
    
         
            +
            "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 8 
     | 
    
         
            +
            without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 9 
     | 
    
         
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 10 
     | 
    
         
            +
            permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 11 
     | 
    
         
            +
            the following conditions:
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be
         
     | 
| 
      
 14 
     | 
    
         
            +
            included in all copies or substantial portions of the Software.
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 17 
     | 
    
         
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 18 
     | 
    
         
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 19 
     | 
    
         
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 20 
     | 
    
         
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 21 
     | 
    
         
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 22 
     | 
    
         
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Ganddyn [](https://travis-ci.org/doc75/ganddyn)
         
     | 
| 
      
 2 
     | 
    
         
            +
            =======
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            This gem allows to update your GANDI DNS zone with the current external IPv4 of your machine.
         
     | 
| 
      
 5 
     | 
    
         
            +
            It duplicate current zone information in the last inactive version of the zone (or a newly
         
     | 
| 
      
 6 
     | 
    
         
            +
            created one if only one version exist). It updates the IPv4 for the name requested and activate
         
     | 
| 
      
 7 
     | 
    
         
            +
            this version.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ## Installation
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Add this line to your application's Gemfile:
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                gem 'ganddyn'
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            And then execute:
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                $ bundle
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            Or install it yourself as:
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                $ gem install ganddyn
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                $ gannddyn hostname.domain.com GANDIAPIKEY /path/to/file/storing/last/ip/updated
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            **Warning**:
         
     | 
| 
      
 28 
     | 
    
         
            +
              - This is an early version not fully tested, use it at your own risk.
         
     | 
| 
      
 29 
     | 
    
         
            +
              - When used on multiple machines for the same domain, it might miss some update in case of concurrent update
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            ## Contributing
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            1. Fork it
         
     | 
| 
      
 34 
     | 
    
         
            +
            2. Create your feature branch (`git checkout -b my-new-feature`)
         
     | 
| 
      
 35 
     | 
    
         
            +
            3. Commit your changes (`git commit -am 'Add some feature'`)
         
     | 
| 
      
 36 
     | 
    
         
            +
            4. Push to the branch (`git push origin my-new-feature`)
         
     | 
| 
      
 37 
     | 
    
         
            +
            5. Create new Pull Request
         
     | 
    
        data/Rakefile
    ADDED
    
    
    
        data/bin/ganddyn
    ADDED
    
    | 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            $LOAD_PATH << './lib'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'ganddyn'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            raise ArgumentError, 'Usage: ganddyn host.domain.com gandi_api_key yaml_file' if ARGV.size != 3
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            begin
         
     | 
| 
      
 8 
     | 
    
         
            +
              cli = Ganddyn::Client.new({:hostname => ARGV[0], :api_key => ARGV[1], :config_file => ARGV[2]})
         
     | 
| 
      
 9 
     | 
    
         
            +
              cli.update
         
     | 
| 
      
 10 
     | 
    
         
            +
              retval = 0
         
     | 
| 
      
 11 
     | 
    
         
            +
            rescue Exception => e
         
     | 
| 
      
 12 
     | 
    
         
            +
              puts e
         
     | 
| 
      
 13 
     | 
    
         
            +
              puts e.backtrace
         
     | 
| 
      
 14 
     | 
    
         
            +
              retval = 1
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            exit retval
         
     | 
    
        data/ganddyn.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,32 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # coding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            lib = File.expand_path('../lib', __FILE__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'ganddyn/version'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Gem::Specification.new do |spec|
         
     | 
| 
      
 7 
     | 
    
         
            +
              spec.name          = 'ganddyn'
         
     | 
| 
      
 8 
     | 
    
         
            +
              spec.version       = Ganddyn::VERSION
         
     | 
| 
      
 9 
     | 
    
         
            +
              spec.authors       = ['Guillaume Virlet']
         
     | 
| 
      
 10 
     | 
    
         
            +
              spec.email         = ['github@virlet.org']
         
     | 
| 
      
 11 
     | 
    
         
            +
              spec.description   = %q{This gem allows to update your GANDI DNS zone with the current external IPv4 of your machine.
         
     | 
| 
      
 12 
     | 
    
         
            +
            It duplicate current zone information in the last inactive version of the zone (or a newly
         
     | 
| 
      
 13 
     | 
    
         
            +
            created one if only one version exist). It updates the IPv4 for the name requested and activate
         
     | 
| 
      
 14 
     | 
    
         
            +
            this version.}
         
     | 
| 
      
 15 
     | 
    
         
            +
              spec.summary       = %q{Update GANDI DNS zone IPv4}
         
     | 
| 
      
 16 
     | 
    
         
            +
              spec.homepage      = 'https://github.com/doc75/ganddyn'
         
     | 
| 
      
 17 
     | 
    
         
            +
              spec.license       = 'MIT'
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              spec.files         = `git ls-files`.split($/)
         
     | 
| 
      
 20 
     | 
    
         
            +
              spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
         
     | 
| 
      
 21 
     | 
    
         
            +
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         
     | 
| 
      
 22 
     | 
    
         
            +
              spec.require_paths = ['lib']
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              spec.add_development_dependency 'bundler', '~> 1.3'
         
     | 
| 
      
 25 
     | 
    
         
            +
              spec.add_development_dependency 'rake', '~>10.3.1'
         
     | 
| 
      
 26 
     | 
    
         
            +
              spec.add_development_dependency 'rspec', '~>2.14.1'
         
     | 
| 
      
 27 
     | 
    
         
            +
              spec.add_development_dependency 'webmock', '~>1.17.4'
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              spec.add_dependency 'gandi', '~>2.0.10'
         
     | 
| 
      
 30 
     | 
    
         
            +
              spec.add_dependency 'highline', '~>1.6.21'
         
     | 
| 
      
 31 
     | 
    
         
            +
              spec.add_dependency 'certified', '~> 0.1.2'
         
     | 
| 
      
 32 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,297 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'gandi'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'yaml'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'highline'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            if RUBY_PLATFORM =~ /mingw32/
         
     | 
| 
      
 8 
     | 
    
         
            +
              require 'certified'
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            module Ganddyn
         
     | 
| 
      
 12 
     | 
    
         
            +
              class Client
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                TTL = 300
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def initialize opts
         
     | 
| 
      
 17 
     | 
    
         
            +
                  raise ArgumentError, 'opts is not a Hash' unless opts.is_a? Hash
         
     | 
| 
      
 18 
     | 
    
         
            +
                  raise ArgumentError, 'opts does not contain key :hostname' unless opts.has_key? :hostname
         
     | 
| 
      
 19 
     | 
    
         
            +
                  raise ArgumentError, 'opts does not contain key :api_key' unless opts.has_key? :api_key
         
     | 
| 
      
 20 
     | 
    
         
            +
                  raise ArgumentError, 'opts does not contain key :config_file' unless opts.has_key? :config_file
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  @debug = false
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  @api_key     = opts[:api_key]
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @config_file = opts[:config_file]
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  tab = opts[:hostname].split('.')
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @name     = tab[0...-2].join('.')
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @domain   = tab[-2..-1].join('.')
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  @terminal = opts.has_key?(:terminal) ? opts[:terminal] : HighLine.new
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 34 
     | 
    
         
            +
                    last_ips_gandi = YAML.load_file @config_file
         
     | 
| 
      
 35 
     | 
    
         
            +
                    print_debug last_ips_gandi.inspect, 2
         
     | 
| 
      
 36 
     | 
    
         
            +
                  rescue => e
         
     | 
| 
      
 37 
     | 
    
         
            +
                    print_debug 'Cannot load config file', 1
         
     | 
| 
      
 38 
     | 
    
         
            +
                    last_ips_gandi = false
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  if last_ips_gandi
         
     | 
| 
      
 42 
     | 
    
         
            +
                    print_debug "last_ips_gandi exist", 2
         
     | 
| 
      
 43 
     | 
    
         
            +
                  else
         
     | 
| 
      
 44 
     | 
    
         
            +
                    print_debug "last_ips_gandi is nil or false", 2
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  print_debug last_ips_gandi.inspect, 2
         
     | 
| 
      
 47 
     | 
    
         
            +
                  @last_ipv4 = (last_ips_gandi && last_ips_gandi[:ipv4].size > 0) ? last_ips_gandi[:ipv4] : nil
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  print_debug "Last IPv4 (form config file):#{@last_ipv4}", 1
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  @cur_ipv4 = nil
         
     | 
| 
      
 52 
     | 
    
         
            +
                  @api      = nil
         
     | 
| 
      
 53 
     | 
    
         
            +
                  @zone_id  = nil
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                # return value:
         
     | 
| 
      
 58 
     | 
    
         
            +
                #   true  => update done
         
     | 
| 
      
 59 
     | 
    
         
            +
                #   false => update not needed
         
     | 
| 
      
 60 
     | 
    
         
            +
                #   nil => no network found
         
     | 
| 
      
 61 
     | 
    
         
            +
                def update
         
     | 
| 
      
 62 
     | 
    
         
            +
                  return nil unless ipv4_available?
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  last_ipv4 = @last_ipv4 ? @last_ipv4 : get_gandi_ipv4
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  update_config = false
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  if @last_ipv4.nil?
         
     | 
| 
      
 69 
     | 
    
         
            +
                    update_config = true
         
     | 
| 
      
 70 
     | 
    
         
            +
                  else
         
     | 
| 
      
 71 
     | 
    
         
            +
                    update_config = true if @last_ipv4.empty?
         
     | 
| 
      
 72 
     | 
    
         
            +
                    update_config = true if last_ipv4 != @last_ipv4
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  print_debug "Last IPv4 (form config file or Gandi):#{last_ipv4}", 1
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  # TODO: save it in YAML file to reduce Gandi queries
         
     | 
| 
      
 78 
     | 
    
         
            +
                  ip_resolv = IpResolver.new
         
     | 
| 
      
 79 
     | 
    
         
            +
                  cur_ipv4 = ipv4_available? ? ip_resolv.get_ipv4 : ''
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  if !cur_ipv4.empty? && cur_ipv4 != last_ipv4
         
     | 
| 
      
 82 
     | 
    
         
            +
                    to_update = cur_ipv4
         
     | 
| 
      
 83 
     | 
    
         
            +
                    update_config = true
         
     | 
| 
      
 84 
     | 
    
         
            +
                  else
         
     | 
| 
      
 85 
     | 
    
         
            +
                    to_update = ''
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  print_debug to_update.inspect, 2
         
     | 
| 
      
 89 
     | 
    
         
            +
                  retval = update_ips to_update
         
     | 
| 
      
 90 
     | 
    
         
            +
                  if retval and update_config
         
     | 
| 
      
 91 
     | 
    
         
            +
                    retval = update_config_file cur_ipv4
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
                  retval
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                private
         
     | 
| 
      
 97 
     | 
    
         
            +
                  # return value:
         
     | 
| 
      
 98 
     | 
    
         
            +
                  #   nil => no network available for IPv4
         
     | 
| 
      
 99 
     | 
    
         
            +
                  #   ''  => no previous IPv4 stored in Ganddi DNS
         
     | 
| 
      
 100 
     | 
    
         
            +
                  #   otherwise return IPv4 address as a string
         
     | 
| 
      
 101 
     | 
    
         
            +
                  def get_gandi_ipv4
         
     | 
| 
      
 102 
     | 
    
         
            +
                    get_record('A') if ipv4_available?
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                  def get_ping_option
         
     | 
| 
      
 106 
     | 
    
         
            +
                    if RUBY_PLATFORM =~ /mingw32/
         
     | 
| 
      
 107 
     | 
    
         
            +
                      return '-n', '> NUL'
         
     | 
| 
      
 108 
     | 
    
         
            +
                    else
         
     | 
| 
      
 109 
     | 
    
         
            +
                      return '-c', '> /dev/null 2>&1'
         
     | 
| 
      
 110 
     | 
    
         
            +
                    end
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  def ipv4_available?
         
     | 
| 
      
 114 
     | 
    
         
            +
                    return @ipv4_avail unless @ipv4_avail.nil?
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                    opt, out = get_ping_option
         
     | 
| 
      
 117 
     | 
    
         
            +
                    @ipv4_avail = system("ping #{opt} 1 8.8.8.8 #{out}")
         
     | 
| 
      
 118 
     | 
    
         
            +
                    if @ipv4_avail
         
     | 
| 
      
 119 
     | 
    
         
            +
                      print_info 'IPv4 network available'
         
     | 
| 
      
 120 
     | 
    
         
            +
                    else
         
     | 
| 
      
 121 
     | 
    
         
            +
                      print_info 'IPv4 network not available'
         
     | 
| 
      
 122 
     | 
    
         
            +
                    end
         
     | 
| 
      
 123 
     | 
    
         
            +
                    @ipv4_avail
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                  def get_record type
         
     | 
| 
      
 127 
     | 
    
         
            +
                    raise ArgumentError, %Q{type is not 'A'} unless type == 'A'
         
     | 
| 
      
 128 
     | 
    
         
            +
                    res = gandi_api.domain.zone.record.list(get_zone_id, 0, {:name => @name, :type => type})
         
     | 
| 
      
 129 
     | 
    
         
            +
                    print_debug res.inspect, 2
         
     | 
| 
      
 130 
     | 
    
         
            +
                    if res.size == 0
         
     | 
| 
      
 131 
     | 
    
         
            +
                      print_debug "record not found: '#{@name}'", 1
         
     | 
| 
      
 132 
     | 
    
         
            +
                      ''
         
     | 
| 
      
 133 
     | 
    
         
            +
                    else
         
     | 
| 
      
 134 
     | 
    
         
            +
                      print_debug "record found: '#{@name}' => #{res[0].value}", 1
         
     | 
| 
      
 135 
     | 
    
         
            +
                      res[0].value
         
     | 
| 
      
 136 
     | 
    
         
            +
                    end
         
     | 
| 
      
 137 
     | 
    
         
            +
                  end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                  def update_ips update
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                    raise(ArgumentError, 'update is not a String') unless update.is_a? String
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                    if update.size == 0
         
     | 
| 
      
 144 
     | 
    
         
            +
                      print_info 'no update needed'
         
     | 
| 
      
 145 
     | 
    
         
            +
                      return true
         
     | 
| 
      
 146 
     | 
    
         
            +
                    end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                    cur_vers, all_vers = get_zone_version
         
     | 
| 
      
 149 
     | 
    
         
            +
                    if all_vers.size == 1
         
     | 
| 
      
 150 
     | 
    
         
            +
                      # create a new version and add it to list of all versions
         
     | 
| 
      
 151 
     | 
    
         
            +
                      new_vers = create_new_zone_version
         
     | 
| 
      
 152 
     | 
    
         
            +
                    else
         
     | 
| 
      
 153 
     | 
    
         
            +
                      all_vers = all_vers - [cur_vers]
         
     | 
| 
      
 154 
     | 
    
         
            +
                      # we take the last version of existing versions (my choice ;-)
         
     | 
| 
      
 155 
     | 
    
         
            +
                      new_vers = all_vers[-1]
         
     | 
| 
      
 156 
     | 
    
         
            +
                      clone_zone_version( cur_vers, new_vers )
         
     | 
| 
      
 157 
     | 
    
         
            +
                    end
         
     | 
| 
      
 158 
     | 
    
         
            +
                    
         
     | 
| 
      
 159 
     | 
    
         
            +
                    retval = false
         
     | 
| 
      
 160 
     | 
    
         
            +
                    if update_ipv4(new_vers, update)
         
     | 
| 
      
 161 
     | 
    
         
            +
                      if activate_updated_version new_vers
         
     | 
| 
      
 162 
     | 
    
         
            +
                        retval = true
         
     | 
| 
      
 163 
     | 
    
         
            +
                        print_info 'update done'
         
     | 
| 
      
 164 
     | 
    
         
            +
                      else
         
     | 
| 
      
 165 
     | 
    
         
            +
                        retval = false
         
     | 
| 
      
 166 
     | 
    
         
            +
                        print_info 'update FAILED'
         
     | 
| 
      
 167 
     | 
    
         
            +
                      end
         
     | 
| 
      
 168 
     | 
    
         
            +
                    end
         
     | 
| 
      
 169 
     | 
    
         
            +
                    retval
         
     | 
| 
      
 170 
     | 
    
         
            +
                  end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                  def activate_updated_version version
         
     | 
| 
      
 173 
     | 
    
         
            +
                    res = gandi_api.domain.zone.version.set(get_zone_id, version)
         
     | 
| 
      
 174 
     | 
    
         
            +
                    if res
         
     | 
| 
      
 175 
     | 
    
         
            +
                      print_debug 'activation of zone version successful', 1
         
     | 
| 
      
 176 
     | 
    
         
            +
                    else
         
     | 
| 
      
 177 
     | 
    
         
            +
                      print_debug 'activation of zone version failed', 1
         
     | 
| 
      
 178 
     | 
    
         
            +
                    end
         
     | 
| 
      
 179 
     | 
    
         
            +
                    res
         
     | 
| 
      
 180 
     | 
    
         
            +
                  end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                  def update_ipv4 zone_version, ip
         
     | 
| 
      
 183 
     | 
    
         
            +
                    update_record zone_version, ip, 'A'
         
     | 
| 
      
 184 
     | 
    
         
            +
                  end
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                  def update_record zone_version, ip, type
         
     | 
| 
      
 187 
     | 
    
         
            +
                    return false if ip.empty?
         
     | 
| 
      
 188 
     | 
    
         
            +
                    retval = false
         
     | 
| 
      
 189 
     | 
    
         
            +
                    records = gandi_api.domain.zone.record.list( get_zone_id,
         
     | 
| 
      
 190 
     | 
    
         
            +
                                                                 zone_version,
         
     | 
| 
      
 191 
     | 
    
         
            +
                                                                 {:name => @name, :type => type} )
         
     | 
| 
      
 192 
     | 
    
         
            +
                    if records.size == 0
         
     | 
| 
      
 193 
     | 
    
         
            +
                      res = gandi_api.domain.zone.record.add( get_zone_id,
         
     | 
| 
      
 194 
     | 
    
         
            +
                                                              zone_version,
         
     | 
| 
      
 195 
     | 
    
         
            +
                                                              { :name  => @name,
         
     | 
| 
      
 196 
     | 
    
         
            +
                                                                :type  => type,
         
     | 
| 
      
 197 
     | 
    
         
            +
                                                                :value => ip,
         
     | 
| 
      
 198 
     | 
    
         
            +
                                                                :ttl   => TTL } )
         
     | 
| 
      
 199 
     | 
    
         
            +
                      retval = true
         
     | 
| 
      
 200 
     | 
    
         
            +
                    else
         
     | 
| 
      
 201 
     | 
    
         
            +
                      records.each do |rec|
         
     | 
| 
      
 202 
     | 
    
         
            +
                        # only update if ip is different
         
     | 
| 
      
 203 
     | 
    
         
            +
                        if rec.value != ip
         
     | 
| 
      
 204 
     | 
    
         
            +
                          res = gandi_api.domain.zone.record.update( get_zone_id,
         
     | 
| 
      
 205 
     | 
    
         
            +
                                                                     zone_version,
         
     | 
| 
      
 206 
     | 
    
         
            +
                                                                     { :id => rec.id },
         
     | 
| 
      
 207 
     | 
    
         
            +
                                                                     { :name  => rec.name,
         
     | 
| 
      
 208 
     | 
    
         
            +
                                                                       :type  => rec.type,
         
     | 
| 
      
 209 
     | 
    
         
            +
                                                                       :value => ip,
         
     | 
| 
      
 210 
     | 
    
         
            +
                                                                       :ttl   => TTL } )
         
     | 
| 
      
 211 
     | 
    
         
            +
                          retval = true
         
     | 
| 
      
 212 
     | 
    
         
            +
                        end
         
     | 
| 
      
 213 
     | 
    
         
            +
                      end
         
     | 
| 
      
 214 
     | 
    
         
            +
                    end
         
     | 
| 
      
 215 
     | 
    
         
            +
                    retval
         
     | 
| 
      
 216 
     | 
    
         
            +
                  end
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                  def clone_zone_version src, dest
         
     | 
| 
      
 219 
     | 
    
         
            +
                    src_list = gandi_api.domain.zone.record.list(get_zone_id, src)
         
     | 
| 
      
 220 
     | 
    
         
            +
                    print_debug src_list.inspect, 2
         
     | 
| 
      
 221 
     | 
    
         
            +
             
     | 
| 
      
 222 
     | 
    
         
            +
                    dest_list = gandi_api.domain.zone.record.list(get_zone_id, dest)
         
     | 
| 
      
 223 
     | 
    
         
            +
                    print_debug dest_list.inspect, 2
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
                    dest_list.each do |elt|
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
      
 227 
     | 
    
         
            +
                      curs = src_list.select { |e| e.name == elt.name && e.type == elt.type }
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
                      if curs.size > 0
         
     | 
| 
      
 230 
     | 
    
         
            +
                        print_debug "\n#{curs.inspect}", 2
         
     | 
| 
      
 231 
     | 
    
         
            +
                        # normally with the same name and same type we should have only 1 record
         
     | 
| 
      
 232 
     | 
    
         
            +
                        cur = curs[0]
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
                        if cur.ttl != elt.ttl || cur.value != elt.value
         
     | 
| 
      
 235 
     | 
    
         
            +
                          print_debug "Updating record (name: #{elt.name} - type: #{elt.type}) to ttl: #{cur.ttl} - value: #{cur.value}", 1
         
     | 
| 
      
 236 
     | 
    
         
            +
                          res = gandi_api.domain.zone.record.update( get_zone_id, dest, { :id => elt.id }, {:name => cur.name, :type => cur.type, :value => cur.value, :ttl => cur.ttl} )
         
     | 
| 
      
 237 
     | 
    
         
            +
                          print_debug res.inspect, 2
         
     | 
| 
      
 238 
     | 
    
         
            +
                        else
         
     | 
| 
      
 239 
     | 
    
         
            +
                          print_debug "record (name: #{elt.name} - type: #{elt.type}) already up-to-date", 1
         
     | 
| 
      
 240 
     | 
    
         
            +
                        end
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
                        src_list = src_list - [cur]
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                      else
         
     | 
| 
      
 245 
     | 
    
         
            +
                        # it does not exist in current zone, let's delete this record
         
     | 
| 
      
 246 
     | 
    
         
            +
                        print_debug "\nDeleting record (name: #{elt.name} - type: #{elt.type})", 1
         
     | 
| 
      
 247 
     | 
    
         
            +
                        res = gandi_api.domain.zone.record.delete( get_zone_id, dest, { :id => elt.id } )
         
     | 
| 
      
 248 
     | 
    
         
            +
                        
         
     | 
| 
      
 249 
     | 
    
         
            +
                        if res == 1
         
     | 
| 
      
 250 
     | 
    
         
            +
                          print_debug "Deletion OK", 2
         
     | 
| 
      
 251 
     | 
    
         
            +
                        else
         
     | 
| 
      
 252 
     | 
    
         
            +
                          print_debug "ERROR: deletion of #{res} records", 2
         
     | 
| 
      
 253 
     | 
    
         
            +
                        end
         
     | 
| 
      
 254 
     | 
    
         
            +
                      end
         
     | 
| 
      
 255 
     | 
    
         
            +
                    end
         
     | 
| 
      
 256 
     | 
    
         
            +
             
     | 
| 
      
 257 
     | 
    
         
            +
                    src_list.each do |cur|
         
     | 
| 
      
 258 
     | 
    
         
            +
                      print_debug "Creating record (name: #{cur.name} - type: #{cur.type} - ttl: #{cur.ttl} - value: #{cur.value}", 1
         
     | 
| 
      
 259 
     | 
    
         
            +
                      res = gandi_api.domain.zone.record.add( get_zone_id, dest, {:name => cur.name, :type => cur.type, :value => cur.value, :ttl => cur.ttl} )
         
     | 
| 
      
 260 
     | 
    
         
            +
                    end
         
     | 
| 
      
 261 
     | 
    
         
            +
                  end
         
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
      
 263 
     | 
    
         
            +
                  def update_config_file ip
         
     | 
| 
      
 264 
     | 
    
         
            +
                    if File.open(@config_file, 'w+') { |f| f.write({:ipv4 => ip}.to_yaml) }
         
     | 
| 
      
 265 
     | 
    
         
            +
                      true
         
     | 
| 
      
 266 
     | 
    
         
            +
                    else
         
     | 
| 
      
 267 
     | 
    
         
            +
                      false
         
     | 
| 
      
 268 
     | 
    
         
            +
                    end
         
     | 
| 
      
 269 
     | 
    
         
            +
                  end
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
      
 271 
     | 
    
         
            +
                  def get_zone_version
         
     | 
| 
      
 272 
     | 
    
         
            +
                    get_zone_id
         
     | 
| 
      
 273 
     | 
    
         
            +
                    infos = gandi_api.domain.zone.info(@zone_id)
         
     | 
| 
      
 274 
     | 
    
         
            +
                    return infos.version, infos.versions
         
     | 
| 
      
 275 
     | 
    
         
            +
                  end
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
      
 277 
     | 
    
         
            +
                  def create_new_zone_version
         
     | 
| 
      
 278 
     | 
    
         
            +
                    gandi_api.domain.zone.version.new_version(@zone_id)
         
     | 
| 
      
 279 
     | 
    
         
            +
                  end
         
     | 
| 
      
 280 
     | 
    
         
            +
             
     | 
| 
      
 281 
     | 
    
         
            +
                  def get_zone_id
         
     | 
| 
      
 282 
     | 
    
         
            +
                    @zone_id ||= gandi_api.domain.info(@domain).zone_id
         
     | 
| 
      
 283 
     | 
    
         
            +
                  end
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
      
 285 
     | 
    
         
            +
                  def gandi_api
         
     | 
| 
      
 286 
     | 
    
         
            +
                    @api ||= Gandi::Session.new(@api_key)
         
     | 
| 
      
 287 
     | 
    
         
            +
                  end
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
      
 289 
     | 
    
         
            +
                  def print_info str
         
     | 
| 
      
 290 
     | 
    
         
            +
                    @terminal.say str
         
     | 
| 
      
 291 
     | 
    
         
            +
                  end
         
     | 
| 
      
 292 
     | 
    
         
            +
             
     | 
| 
      
 293 
     | 
    
         
            +
                  def print_debug str, level = 1
         
     | 
| 
      
 294 
     | 
    
         
            +
                    @terminal.say str if @debug and @debug >= level
         
     | 
| 
      
 295 
     | 
    
         
            +
                  end
         
     | 
| 
      
 296 
     | 
    
         
            +
              end
         
     | 
| 
      
 297 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'net/http'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Ganddyn
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              class IpResolver
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                # urls: hash or ipv4 and ipv6 url services
         
     | 
| 
      
 8 
     | 
    
         
            +
                #       { :ipv4 => 'http://ipv4_url', :ipv6 => 'http://ipv6_url'}
         
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize urls = {}
         
     | 
| 
      
 10 
     | 
    
         
            +
                  raise ArgumentError, 'urls is not a Hash' unless urls.is_a? Hash
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  @ipv4_url = urls.has_key?(:ipv4) ? urls[:ipv4] : "http://v4.ipv6-test.com/api/myip.php"
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @ipv6_url = urls.has_key?(:ipv6) ? urls[:ipv6] : "http://v6.ipv6-test.com/api/myip.php"
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def get_ipv4
         
     | 
| 
      
 17 
     | 
    
         
            +
                  get_url @ipv4_url
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def get_ipv6
         
     | 
| 
      
 21 
     | 
    
         
            +
                  get_url @ipv6_url
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                private
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def get_url( iUrl )
         
     | 
| 
      
 26 
     | 
    
         
            +
                    retval = nil
         
     | 
| 
      
 27 
     | 
    
         
            +
                    uri = URI(iUrl)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 29 
     | 
    
         
            +
                      res = Net::HTTP.get_response(uri)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      if res.code == '200'
         
     | 
| 
      
 31 
     | 
    
         
            +
                        retval = res.body
         
     | 
| 
      
 32 
     | 
    
         
            +
                      end
         
     | 
| 
      
 33 
     | 
    
         
            +
                    rescue SocketError => e
         
     | 
| 
      
 34 
     | 
    
         
            +
                      # normally it happens if the server name is invalid
         
     | 
| 
      
 35 
     | 
    
         
            +
                      # or if no network is available
         
     | 
| 
      
 36 
     | 
    
         
            +
                      # let's return nil
         
     | 
| 
      
 37 
     | 
    
         
            +
                    rescue Exception => e
         
     | 
| 
      
 38 
     | 
    
         
            +
                      # normally it happen if the machine has no ipv6 support
         
     | 
| 
      
 39 
     | 
    
         
            +
                      # let's return nil
         
     | 
| 
      
 40 
     | 
    
         
            +
                    end
         
     | 
| 
      
 41 
     | 
    
         
            +
                    retval
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/ganddyn.rb
    ADDED
    
    | 
         @@ -0,0 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Add the directory containing this file to the start of the load path if it isn't there already.
         
     | 
| 
      
 2 
     | 
    
         
            +
            #$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'ganddyn/ipresolver'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'ganddyn/client'
         
     | 
| 
         @@ -0,0 +1,559 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'ganddyn'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe Ganddyn::Client do
         
     | 
| 
      
 6 
     | 
    
         
            +
              before :each do
         
     | 
| 
      
 7 
     | 
    
         
            +
                @input = StringIO.new
         
     | 
| 
      
 8 
     | 
    
         
            +
                @output = StringIO.new
         
     | 
| 
      
 9 
     | 
    
         
            +
                @terminal = HighLine.new(@input, @output)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                @ipv4 = '12.34.56.78'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                @cur_ver = 123
         
     | 
| 
      
 14 
     | 
    
         
            +
                @other_ver = 456
         
     | 
| 
      
 15 
     | 
    
         
            +
                @vers = [@cur_ver, @other_ver]
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                @mash   = Hashie::Mash.new({:version => @cur_ver, :versions => [@cur_ver, @other_ver]})
         
     | 
| 
      
 18 
     | 
    
         
            +
                @domain = 'domain.com'
         
     | 
| 
      
 19 
     | 
    
         
            +
                @name   = 'rspec'
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                @host = { :hostname    => 'rspec.domain.com' }
         
     | 
| 
      
 22 
     | 
    
         
            +
                @key  = { :api_key     => 'FAKEAPIKEY' }
         
     | 
| 
      
 23 
     | 
    
         
            +
                @cfg  = { :config_file => '/etc/ganddyn.yaml' }
         
     | 
| 
      
 24 
     | 
    
         
            +
                @param = @host.merge(@key).merge(@cfg)
         
     | 
| 
      
 25 
     | 
    
         
            +
                allow(YAML).to receive(:load_file).and_return({:ipv4 => @ipv4})
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                @api = double('api_gandi')
         
     | 
| 
      
 28 
     | 
    
         
            +
                allow(@api).to receive(:domain).and_return(@api)
         
     | 
| 
      
 29 
     | 
    
         
            +
                allow(@api).to receive(:zone).and_return(@api)
         
     | 
| 
      
 30 
     | 
    
         
            +
                allow(@api).to receive(:info).and_return(@mash)
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                allow(@api).to receive(:version).and_return(@api)
         
     | 
| 
      
 33 
     | 
    
         
            +
                allow(@api).to receive(:new_version).and_return(3)
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                allow(@api).to receive(:record).and_return(@api)
         
     | 
| 
      
 36 
     | 
    
         
            +
                allow(@api).to receive(:add).and_return([])
         
     | 
| 
      
 37 
     | 
    
         
            +
                allow(@api).to receive(:delete).and_return(1)
         
     | 
| 
      
 38 
     | 
    
         
            +
                allow(@api).to receive(:update).and_return([])
         
     | 
| 
      
 39 
     | 
    
         
            +
                allow(@api).to receive(:list).and_return([])
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                allow(@api).to receive(:version).and_return(@api)
         
     | 
| 
      
 42 
     | 
    
         
            +
                allow(@api).to receive(:set).and_return(true)
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                allow_any_instance_of(Ganddyn::Client).to receive(:update_config_file).and_return(true)
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              describe '#initialize' do
         
     | 
| 
      
 48 
     | 
    
         
            +
                before :each do
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
                it 'takes 1 parameters' do
         
     | 
| 
      
 51 
     | 
    
         
            +
                  Ganddyn::Client.new( @param ).should be_a Ganddyn::Client
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                it 'raises an error if parameter opts is not a Hash' do
         
     | 
| 
      
 55 
     | 
    
         
            +
                  expect { Ganddyn::Client.new('rspec.domain.com') }.to raise_error(ArgumentError, /opts is not a Hash/)
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                it 'raises an error if parameter opts does not contain :hostname key' do
         
     | 
| 
      
 59 
     | 
    
         
            +
                  expect { Ganddyn::Client.new( {:host_name => 'rspec.domain.com'}.merge(@key).merge(@cfg)) }.to raise_error(ArgumentError, /opts does not contain key :hostname/)
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                it 'raises an error if parameter opts does not contain :api_key key' do
         
     | 
| 
      
 63 
     | 
    
         
            +
                  expect { Ganddyn::Client.new({:apikey => 'FAKEAPIKEY'}.merge(@host).merge(@cfg)) }.to raise_error(ArgumentError, /opts does not contain key :api_key/)
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                it 'raises an error if parameter opts does not contain :config_file key' do
         
     | 
| 
      
 67 
     | 
    
         
            +
                  expect { Ganddyn::Client.new({ :configfile => '/etc/ganddyn.yaml'}.merge(@host).merge(@key)) }.to raise_error(ArgumentError, /opts does not contain key :config_file/)
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                it 'loads the config file' do
         
     | 
| 
      
 71 
     | 
    
         
            +
                  expect(YAML).to receive(:load_file).with(@cfg[:config_file]).and_return({:ipv4 => @ipv4})
         
     | 
| 
      
 72 
     | 
    
         
            +
                  Ganddyn::Client.new( @param )
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              describe '#update' do
         
     | 
| 
      
 77 
     | 
    
         
            +
                before :each do
         
     | 
| 
      
 78 
     | 
    
         
            +
                  allow_any_instance_of(Ganddyn::IpResolver).to receive(:get_ipv4).and_return('11.22.33.44')
         
     | 
| 
      
 79 
     | 
    
         
            +
                  @gand = Ganddyn::Client.new( @param.merge({:terminal => @terminal}) )
         
     | 
| 
      
 80 
     | 
    
         
            +
                  allow(@gand).to receive(:gandi_api).and_return(@api)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  allow(@gand).to receive(:system).and_return(true)
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                context 'when yaml config file is not found' do
         
     | 
| 
      
 85 
     | 
    
         
            +
                  before :each do
         
     | 
| 
      
 86 
     | 
    
         
            +
                    expect(YAML).to receive(:load_file).and_return(false)
         
     | 
| 
      
 87 
     | 
    
         
            +
                    @gand = Ganddyn::Client.new( @param.merge({:terminal => @terminal}) )
         
     | 
| 
      
 88 
     | 
    
         
            +
                    allow(@gand).to receive(:gandi_api).and_return(@api)
         
     | 
| 
      
 89 
     | 
    
         
            +
                    allow(@gand).to receive(:system).and_return(true)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    allow(@gand).to receive(:get_record)
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                  it 'asks gandi for ipv4' do
         
     | 
| 
      
 94 
     | 
    
         
            +
                    expect(@gand).to receive(:get_record).with('A').and_return(@ipv4)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    expect(@gand.update).to be_true
         
     | 
| 
      
 96 
     | 
    
         
            +
                  end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                context 'when yaml config file exist' do
         
     | 
| 
      
 101 
     | 
    
         
            +
                  it 'does not ask Gandi' do
         
     | 
| 
      
 102 
     | 
    
         
            +
                    allow(@gand).to receive(:get_record)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    expect(@gand.update).to be_true
         
     | 
| 
      
 104 
     | 
    
         
            +
                    expect(@gand).to_not have_received(:get_record)
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                context 'when no network' do
         
     | 
| 
      
 109 
     | 
    
         
            +
                  before :each do
         
     | 
| 
      
 110 
     | 
    
         
            +
                    allow(@gand).to receive(:system).and_return(false)
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  it 'does not ask for IPv4 information' do
         
     | 
| 
      
 114 
     | 
    
         
            +
                    expect_any_instance_of(Ganddyn::IpResolver).to_not receive(:get_ipv4)
         
     | 
| 
      
 115 
     | 
    
         
            +
                    expect(@gand.update).to be_nil
         
     | 
| 
      
 116 
     | 
    
         
            +
                  end
         
     | 
| 
      
 117 
     | 
    
         
            +
                end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                context 'when no ip to update' do
         
     | 
| 
      
 120 
     | 
    
         
            +
                  before :each do
         
     | 
| 
      
 121 
     | 
    
         
            +
                    allow_any_instance_of(Ganddyn::IpResolver).to receive(:get_ipv4).and_return('')
         
     | 
| 
      
 122 
     | 
    
         
            +
                  end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                  it 'returns true' do
         
     | 
| 
      
 125 
     | 
    
         
            +
                    expect(@gand.update).to be_true
         
     | 
| 
      
 126 
     | 
    
         
            +
                  end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                  it 'does not modify the yaml config file' do
         
     | 
| 
      
 129 
     | 
    
         
            +
                    expect(@gand).to_not receive(:update_config_file)
         
     | 
| 
      
 130 
     | 
    
         
            +
                    @gand.update
         
     | 
| 
      
 131 
     | 
    
         
            +
                  end
         
     | 
| 
      
 132 
     | 
    
         
            +
                end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                context 'when ip to update' do
         
     | 
| 
      
 135 
     | 
    
         
            +
                  it 'updates the ip' do
         
     | 
| 
      
 136 
     | 
    
         
            +
                    expect(@gand.update).to be_true
         
     | 
| 
      
 137 
     | 
    
         
            +
                  end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                  it 'updates the yaml config file content' do
         
     | 
| 
      
 140 
     | 
    
         
            +
                    expect(@gand).to receive(:update_config_file).and_return(true)
         
     | 
| 
      
 141 
     | 
    
         
            +
                    @gand.update
         
     | 
| 
      
 142 
     | 
    
         
            +
                  end
         
     | 
| 
      
 143 
     | 
    
         
            +
                end
         
     | 
| 
      
 144 
     | 
    
         
            +
              end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            describe_internally Ganddyn::Client do
         
     | 
| 
      
 149 
     | 
    
         
            +
              before :each do
         
     | 
| 
      
 150 
     | 
    
         
            +
                @input = StringIO.new
         
     | 
| 
      
 151 
     | 
    
         
            +
                @output = StringIO.new
         
     | 
| 
      
 152 
     | 
    
         
            +
                @terminal = HighLine.new(@input, @output)
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                @ipv4 = '12.34.56.78'
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                @cur_ver = 123
         
     | 
| 
      
 157 
     | 
    
         
            +
                @other_ver = 456
         
     | 
| 
      
 158 
     | 
    
         
            +
                @vers = [@cur_ver, @other_ver]
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                @mash   = Hashie::Mash.new({:version => @cur_ver, :versions => @vers})
         
     | 
| 
      
 161 
     | 
    
         
            +
                @domain = 'domain.com'
         
     | 
| 
      
 162 
     | 
    
         
            +
                @name   = 'rspec'
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                @host = { :hostname    => 'rspec.domain.com' }
         
     | 
| 
      
 165 
     | 
    
         
            +
                @key  = { :api_key     => 'FAKEAPIKEY' }
         
     | 
| 
      
 166 
     | 
    
         
            +
                @cfg  = { :config_file => '/etc/ganddyn.yaml' }
         
     | 
| 
      
 167 
     | 
    
         
            +
                @param = @host.merge(@key).merge(@cfg)
         
     | 
| 
      
 168 
     | 
    
         
            +
                allow(YAML).to receive(:load_file).and_return({:ipv4 => @ipv4})
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                @api = double('api_gandi')
         
     | 
| 
      
 171 
     | 
    
         
            +
                allow(@api).to receive(:domain).and_return(@api)
         
     | 
| 
      
 172 
     | 
    
         
            +
                allow(@api).to receive(:zone).and_return(@api)
         
     | 
| 
      
 173 
     | 
    
         
            +
                allow(@api).to receive(:info).and_return(@mash)
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
                allow(@api).to receive(:version).and_return(@api)
         
     | 
| 
      
 176 
     | 
    
         
            +
                allow(@api).to receive(:new_version).and_return(3)
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
                allow(@api).to receive(:record).and_return(@api)
         
     | 
| 
      
 179 
     | 
    
         
            +
                allow(@api).to receive(:add).and_return([])
         
     | 
| 
      
 180 
     | 
    
         
            +
                allow(@api).to receive(:delete).and_return(1)
         
     | 
| 
      
 181 
     | 
    
         
            +
                allow(@api).to receive(:update).and_return([])
         
     | 
| 
      
 182 
     | 
    
         
            +
                allow(@api).to receive(:list).and_return([])
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
                allow(@api).to receive(:version).and_return(@api)
         
     | 
| 
      
 185 
     | 
    
         
            +
                allow(@api).to receive(:set).and_return(true)
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                @gand = Ganddyn::Client.new( @param.merge({:terminal => @terminal}) )
         
     | 
| 
      
 188 
     | 
    
         
            +
                allow(@gand).to receive(:gandi_api).and_return(@api)
         
     | 
| 
      
 189 
     | 
    
         
            +
                allow(@gand).to receive(:system).and_return(true)
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                allow_any_instance_of(Ganddyn::Client).to receive(:update_config_file).and_return(true)
         
     | 
| 
      
 192 
     | 
    
         
            +
              end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
              describe '#get_zone_id' do
         
     | 
| 
      
 195 
     | 
    
         
            +
                it 'returns the current zone id' do
         
     | 
| 
      
 196 
     | 
    
         
            +
                  @api.should_receive(:info).with(@domain).and_return(Hashie::Mash.new({:zone_id => 666}))
         
     | 
| 
      
 197 
     | 
    
         
            +
                  @gand.get_zone_id.should == 666
         
     | 
| 
      
 198 
     | 
    
         
            +
                end
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
                it 'calls gandi api only once' do
         
     | 
| 
      
 201 
     | 
    
         
            +
                  @api.should_receive(:info).once.with(@domain).and_return(Hashie::Mash.new({:zone_id => 666}))
         
     | 
| 
      
 202 
     | 
    
         
            +
                  @gand.get_zone_id.should == 666
         
     | 
| 
      
 203 
     | 
    
         
            +
                  @gand.get_zone_id.should == 666
         
     | 
| 
      
 204 
     | 
    
         
            +
                end
         
     | 
| 
      
 205 
     | 
    
         
            +
              end
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
              describe '#create_new_zone_version' do
         
     | 
| 
      
 208 
     | 
    
         
            +
                pending 'not really necessary'
         
     | 
| 
      
 209 
     | 
    
         
            +
              end
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
              describe '#get_zone_version' do
         
     | 
| 
      
 212 
     | 
    
         
            +
                it 'returns 2 values' do
         
     | 
| 
      
 213 
     | 
    
         
            +
                  version, versions = @gand.get_zone_version
         
     | 
| 
      
 214 
     | 
    
         
            +
                  version.should == @cur_ver
         
     | 
| 
      
 215 
     | 
    
         
            +
                  versions.should == @vers
         
     | 
| 
      
 216 
     | 
    
         
            +
                end
         
     | 
| 
      
 217 
     | 
    
         
            +
              end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
              describe '#get_record' do
         
     | 
| 
      
 220 
     | 
    
         
            +
                before :each do
         
     | 
| 
      
 221 
     | 
    
         
            +
                  @type   = 'A'
         
     | 
| 
      
 222 
     | 
    
         
            +
                  @filter = { :name => @name, :type => @type }
         
     | 
| 
      
 223 
     | 
    
         
            +
                  @res    = Hashie::Mash.new({:value => @ipv4})
         
     | 
| 
      
 224 
     | 
    
         
            +
                end
         
     | 
| 
      
 225 
     | 
    
         
            +
             
     | 
| 
      
 226 
     | 
    
         
            +
                it 'takes 1 parameter as argument' do
         
     | 
| 
      
 227 
     | 
    
         
            +
                  @api.should_receive(:list).with(anything(), 0, @filter).and_return([@res])
         
     | 
| 
      
 228 
     | 
    
         
            +
                  @gand.get_record('A')
         
     | 
| 
      
 229 
     | 
    
         
            +
                end
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
                context 'when Gandi returns a record' do
         
     | 
| 
      
 232 
     | 
    
         
            +
                  before :each do
         
     | 
| 
      
 233 
     | 
    
         
            +
                    expect(@api).to receive(:list).with(anything(), 0, @filter).and_return([@res])
         
     | 
| 
      
 234 
     | 
    
         
            +
                  end
         
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
                  it 'returns the IPv4 address' do
         
     | 
| 
      
 237 
     | 
    
         
            +
                    @gand.get_record('A').should == @ipv4
         
     | 
| 
      
 238 
     | 
    
         
            +
                  end
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
                  # it 'output record found with value' do
         
     | 
| 
      
 241 
     | 
    
         
            +
                  #   @gand.get_record('A')
         
     | 
| 
      
 242 
     | 
    
         
            +
                  #   expect(@output.string).to match /record found: '#{@name}' => #{@ipv4}/
         
     | 
| 
      
 243 
     | 
    
         
            +
                  # end
         
     | 
| 
      
 244 
     | 
    
         
            +
                end
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
      
 246 
     | 
    
         
            +
                context 'when Gandi returns no record' do
         
     | 
| 
      
 247 
     | 
    
         
            +
                  before :each do
         
     | 
| 
      
 248 
     | 
    
         
            +
                    expect(@api).to receive(:list).with(anything(), 0, @filter).and_return([])
         
     | 
| 
      
 249 
     | 
    
         
            +
                  end
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
                  it 'returns an empty string if Gandi returns no record' do
         
     | 
| 
      
 252 
     | 
    
         
            +
                    expect(@gand.get_record('A')).to eq ''
         
     | 
| 
      
 253 
     | 
    
         
            +
                  end
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
      
 255 
     | 
    
         
            +
                  # it 'output "record not found"' do
         
     | 
| 
      
 256 
     | 
    
         
            +
                  #   @gand.get_record('A')
         
     | 
| 
      
 257 
     | 
    
         
            +
                  #   expect(@output.string).to match /record not found: '#{@name}'/
         
     | 
| 
      
 258 
     | 
    
         
            +
                  # end
         
     | 
| 
      
 259 
     | 
    
         
            +
                end
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
                it 'raises an error if type is not A' do
         
     | 
| 
      
 262 
     | 
    
         
            +
                  expect { @gand.get_record('AA') }.to raise_error(ArgumentError, /type is not 'A'/)
         
     | 
| 
      
 263 
     | 
    
         
            +
                end
         
     | 
| 
      
 264 
     | 
    
         
            +
              end
         
     | 
| 
      
 265 
     | 
    
         
            +
             
     | 
| 
      
 266 
     | 
    
         
            +
              describe '#get_gandi_ipv4' do
         
     | 
| 
      
 267 
     | 
    
         
            +
                before :each do
         
     | 
| 
      
 268 
     | 
    
         
            +
                  @type   = 'A'
         
     | 
| 
      
 269 
     | 
    
         
            +
                  @filter = { :name => @name, :type => @type }
         
     | 
| 
      
 270 
     | 
    
         
            +
                  @res    = Hashie::Mash.new({:value => @ipv4})
         
     | 
| 
      
 271 
     | 
    
         
            +
                end
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
                it 'retrieve the record A from Gandi DNS' do
         
     | 
| 
      
 274 
     | 
    
         
            +
                  expect(@api).to receive(:list).with(anything(), 0, @filter).and_return([@res])
         
     | 
| 
      
 275 
     | 
    
         
            +
                  expect(@gand.get_gandi_ipv4).to eq @ipv4
         
     | 
| 
      
 276 
     | 
    
         
            +
                end
         
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
      
 278 
     | 
    
         
            +
                it 'returns nil if IPv4 network is not available' do
         
     | 
| 
      
 279 
     | 
    
         
            +
                  allow(@gand).to receive(:get_record).and_return('1.2.3.4')
         
     | 
| 
      
 280 
     | 
    
         
            +
                  expect(@gand).to receive(:ipv4_available?).and_return(false)
         
     | 
| 
      
 281 
     | 
    
         
            +
                  expect(@gand.get_gandi_ipv4).to be_nil
         
     | 
| 
      
 282 
     | 
    
         
            +
                  expect(@gand).to_not have_received(:get_record)
         
     | 
| 
      
 283 
     | 
    
         
            +
                end
         
     | 
| 
      
 284 
     | 
    
         
            +
              end
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
      
 286 
     | 
    
         
            +
              describe '#update_record' do
         
     | 
| 
      
 287 
     | 
    
         
            +
                before :each do
         
     | 
| 
      
 288 
     | 
    
         
            +
                  @type = 'A'
         
     | 
| 
      
 289 
     | 
    
         
            +
                  @rec  = { :name => @name, :type => @type, :value => @ipv4, :ttl => Ganddyn::Client::TTL }
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
      
 291 
     | 
    
         
            +
                end
         
     | 
| 
      
 292 
     | 
    
         
            +
             
     | 
| 
      
 293 
     | 
    
         
            +
                it 'takes 3 arguments' do
         
     | 
| 
      
 294 
     | 
    
         
            +
                  expect(@gand.update_record( @cur_ver, @ipv4, 'A')).to be_true
         
     | 
| 
      
 295 
     | 
    
         
            +
                end
         
     | 
| 
      
 296 
     | 
    
         
            +
             
     | 
| 
      
 297 
     | 
    
         
            +
                context 'when input ip is empty' do
         
     | 
| 
      
 298 
     | 
    
         
            +
                  it 'returns false' do
         
     | 
| 
      
 299 
     | 
    
         
            +
                    expect(@gand.update_record( @cur_ver, '', 'A')).to be_false
         
     | 
| 
      
 300 
     | 
    
         
            +
                  end
         
     | 
| 
      
 301 
     | 
    
         
            +
                end 
         
     | 
| 
      
 302 
     | 
    
         
            +
             
     | 
| 
      
 303 
     | 
    
         
            +
                context 'when record does not exist yet' do
         
     | 
| 
      
 304 
     | 
    
         
            +
                  it 'adds a new record' do
         
     | 
| 
      
 305 
     | 
    
         
            +
                    expect(@gand.update_record( @cur_ver, @ipv4, 'A')).to be_true
         
     | 
| 
      
 306 
     | 
    
         
            +
                    expect(@api).to have_received(:add).with(anything, @cur_ver, @rec )
         
     | 
| 
      
 307 
     | 
    
         
            +
                    expect(@api).to_not have_received(:update)
         
     | 
| 
      
 308 
     | 
    
         
            +
                  end
         
     | 
| 
      
 309 
     | 
    
         
            +
                end
         
     | 
| 
      
 310 
     | 
    
         
            +
             
     | 
| 
      
 311 
     | 
    
         
            +
                context 'when record already exist' do
         
     | 
| 
      
 312 
     | 
    
         
            +
                  before :each do
         
     | 
| 
      
 313 
     | 
    
         
            +
                    @filter = { :name => @name, :type => @type }
         
     | 
| 
      
 314 
     | 
    
         
            +
                    @res    = Hashie::Mash.new({:value => @ipv4})
         
     | 
| 
      
 315 
     | 
    
         
            +
                    expect(@api).to receive(:list).with(anything(), @cur_ver, @filter).and_return([@res])
         
     | 
| 
      
 316 
     | 
    
         
            +
                  end
         
     | 
| 
      
 317 
     | 
    
         
            +
             
     | 
| 
      
 318 
     | 
    
         
            +
                  context 'and ip is different' do
         
     | 
| 
      
 319 
     | 
    
         
            +
                    it 'updates the record' do
         
     | 
| 
      
 320 
     | 
    
         
            +
                      @gand.update_record( @cur_ver, "#{@ipv4}1", 'A')
         
     | 
| 
      
 321 
     | 
    
         
            +
                      expect(@api).to_not have_received(:add)
         
     | 
| 
      
 322 
     | 
    
         
            +
                      expect(@api).to have_received(:update).once
         
     | 
| 
      
 323 
     | 
    
         
            +
                    end
         
     | 
| 
      
 324 
     | 
    
         
            +
             
     | 
| 
      
 325 
     | 
    
         
            +
                    it 'returns true' do
         
     | 
| 
      
 326 
     | 
    
         
            +
                      expect(@gand.update_record( @cur_ver, "#{@ipv4}1", 'A')).to be_true
         
     | 
| 
      
 327 
     | 
    
         
            +
                    end
         
     | 
| 
      
 328 
     | 
    
         
            +
                  end
         
     | 
| 
      
 329 
     | 
    
         
            +
             
     | 
| 
      
 330 
     | 
    
         
            +
                  context 'and ip is the same' do
         
     | 
| 
      
 331 
     | 
    
         
            +
                    it 'does not update the record' do
         
     | 
| 
      
 332 
     | 
    
         
            +
                      @gand.update_record( @cur_ver, @ipv4, 'A')
         
     | 
| 
      
 333 
     | 
    
         
            +
                      expect(@api).to_not have_received(:add)
         
     | 
| 
      
 334 
     | 
    
         
            +
                      expect(@api).to_not have_received(:update)
         
     | 
| 
      
 335 
     | 
    
         
            +
                    end
         
     | 
| 
      
 336 
     | 
    
         
            +
             
     | 
| 
      
 337 
     | 
    
         
            +
                    it 'returns false' do
         
     | 
| 
      
 338 
     | 
    
         
            +
                      expect(@gand.update_record( @cur_ver, @ipv4, 'A')).to be_false
         
     | 
| 
      
 339 
     | 
    
         
            +
                    end
         
     | 
| 
      
 340 
     | 
    
         
            +
                  end
         
     | 
| 
      
 341 
     | 
    
         
            +
                end
         
     | 
| 
      
 342 
     | 
    
         
            +
              end
         
     | 
| 
      
 343 
     | 
    
         
            +
             
     | 
| 
      
 344 
     | 
    
         
            +
              describe '#clone_zone_version' do
         
     | 
| 
      
 345 
     | 
    
         
            +
                before :each do
         
     | 
| 
      
 346 
     | 
    
         
            +
                  @src = 111
         
     | 
| 
      
 347 
     | 
    
         
            +
                  @src_ret = [ 123, 456 ].map do |id|
         
     | 
| 
      
 348 
     | 
    
         
            +
                                Hashie::Mash.new({ :id    => id,
         
     | 
| 
      
 349 
     | 
    
         
            +
                                                   :name  => "name#{id}",
         
     | 
| 
      
 350 
     | 
    
         
            +
                                                   :type  => "type#{id}",
         
     | 
| 
      
 351 
     | 
    
         
            +
                                                   :value => "value#{id}",
         
     | 
| 
      
 352 
     | 
    
         
            +
                                                   :ttl   => "ttl#{id}" })
         
     | 
| 
      
 353 
     | 
    
         
            +
                              end
         
     | 
| 
      
 354 
     | 
    
         
            +
                  @dest = 222
         
     | 
| 
      
 355 
     | 
    
         
            +
                  @dest_ret = [ 123, 789 ].map do |id|
         
     | 
| 
      
 356 
     | 
    
         
            +
                                Hashie::Mash.new({ :id    => id,
         
     | 
| 
      
 357 
     | 
    
         
            +
                                                   :name  => "name#{id}",
         
     | 
| 
      
 358 
     | 
    
         
            +
                                                   :type  => "type#{id}",
         
     | 
| 
      
 359 
     | 
    
         
            +
                                                   :value => "value#{id}-dest",
         
     | 
| 
      
 360 
     | 
    
         
            +
                                                   :ttl   => "ttl#{id}-dest" })
         
     | 
| 
      
 361 
     | 
    
         
            +
                              end
         
     | 
| 
      
 362 
     | 
    
         
            +
                  allow(@api).to receive(:list).with(anything(), @src).and_return(@src_ret)
         
     | 
| 
      
 363 
     | 
    
         
            +
                  allow(@api).to receive(:list).with(anything(), @dest).and_return(@dest_ret)
         
     | 
| 
      
 364 
     | 
    
         
            +
                end
         
     | 
| 
      
 365 
     | 
    
         
            +
             
     | 
| 
      
 366 
     | 
    
         
            +
                it 'get the information from source zone' do
         
     | 
| 
      
 367 
     | 
    
         
            +
                  expect(@api).to receive(:list).with(anything(), @src).and_return(@src_ret)
         
     | 
| 
      
 368 
     | 
    
         
            +
                  @gand.clone_zone_version @src, @dest
         
     | 
| 
      
 369 
     | 
    
         
            +
                end
         
     | 
| 
      
 370 
     | 
    
         
            +
                
         
     | 
| 
      
 371 
     | 
    
         
            +
                it 'get the information from destination zone' do
         
     | 
| 
      
 372 
     | 
    
         
            +
                  expect(@api).to receive(:list).with(anything(), @dest).and_return(@dest_ret)
         
     | 
| 
      
 373 
     | 
    
         
            +
                  @gand.clone_zone_version @src, @dest
         
     | 
| 
      
 374 
     | 
    
         
            +
                end
         
     | 
| 
      
 375 
     | 
    
         
            +
             
     | 
| 
      
 376 
     | 
    
         
            +
                it 'deletes the record existing in destination zone but not in source zone' do
         
     | 
| 
      
 377 
     | 
    
         
            +
                  expect(@api).to receive(:delete).with(anything(), @dest, {:id => 789})
         
     | 
| 
      
 378 
     | 
    
         
            +
                  @gand.clone_zone_version @src, @dest
         
     | 
| 
      
 379 
     | 
    
         
            +
                end
         
     | 
| 
      
 380 
     | 
    
         
            +
             
     | 
| 
      
 381 
     | 
    
         
            +
                it 'update the record existing in both zone' do
         
     | 
| 
      
 382 
     | 
    
         
            +
                  ret = @src_ret[0].to_hash.inject({}) { |acc,(k,v)| acc[k.to_sym] = v if k != 'id'; acc }
         
     | 
| 
      
 383 
     | 
    
         
            +
                  expect(@api).to receive(:update).with(anything(), @dest, {:id => 123}, ret)
         
     | 
| 
      
 384 
     | 
    
         
            +
                  @gand.clone_zone_version @src, @dest
         
     | 
| 
      
 385 
     | 
    
         
            +
                end
         
     | 
| 
      
 386 
     | 
    
         
            +
             
     | 
| 
      
 387 
     | 
    
         
            +
                it 'create the record existing only in source zone' do
         
     | 
| 
      
 388 
     | 
    
         
            +
                  ret = @src_ret[1].to_hash.inject({}) { |acc,(k,v)| acc[k.to_sym] = v if k != 'id'; acc }
         
     | 
| 
      
 389 
     | 
    
         
            +
                  expect(@api).to receive(:add).with(anything(), @dest, ret)
         
     | 
| 
      
 390 
     | 
    
         
            +
                  @gand.clone_zone_version @src, @dest
         
     | 
| 
      
 391 
     | 
    
         
            +
                end
         
     | 
| 
      
 392 
     | 
    
         
            +
              end
         
     | 
| 
      
 393 
     | 
    
         
            +
             
     | 
| 
      
 394 
     | 
    
         
            +
              describe '#activate_updated_version' do
         
     | 
| 
      
 395 
     | 
    
         
            +
                context 'when activation succeeded' do
         
     | 
| 
      
 396 
     | 
    
         
            +
                  it 'returns true' do
         
     | 
| 
      
 397 
     | 
    
         
            +
                    expect(@gand.activate_updated_version(2)).to be_true
         
     | 
| 
      
 398 
     | 
    
         
            +
                  end
         
     | 
| 
      
 399 
     | 
    
         
            +
             
     | 
| 
      
 400 
     | 
    
         
            +
                  # it 'output activation of zone version successful' do
         
     | 
| 
      
 401 
     | 
    
         
            +
                  #   @gand.activate_updated_version(2)
         
     | 
| 
      
 402 
     | 
    
         
            +
                  #   expect(@output.string).to match /activation of zone version successful/
         
     | 
| 
      
 403 
     | 
    
         
            +
                  # end
         
     | 
| 
      
 404 
     | 
    
         
            +
                end
         
     | 
| 
      
 405 
     | 
    
         
            +
             
     | 
| 
      
 406 
     | 
    
         
            +
                context 'when activation failed' do
         
     | 
| 
      
 407 
     | 
    
         
            +
                  before :each do
         
     | 
| 
      
 408 
     | 
    
         
            +
                    expect(@api).to receive(:set).with(anything(), 9).and_return(false)
         
     | 
| 
      
 409 
     | 
    
         
            +
                  end
         
     | 
| 
      
 410 
     | 
    
         
            +
                  it 'returns false' do
         
     | 
| 
      
 411 
     | 
    
         
            +
                    expect(@gand.activate_updated_version(9)).to be_false
         
     | 
| 
      
 412 
     | 
    
         
            +
                  end
         
     | 
| 
      
 413 
     | 
    
         
            +
             
     | 
| 
      
 414 
     | 
    
         
            +
                  # it 'output activation of zone version failed' do
         
     | 
| 
      
 415 
     | 
    
         
            +
                  #   @gand.activate_updated_version(9)
         
     | 
| 
      
 416 
     | 
    
         
            +
                  #   expect(@output.string).to match /activation of zone version failed/
         
     | 
| 
      
 417 
     | 
    
         
            +
                  # end
         
     | 
| 
      
 418 
     | 
    
         
            +
             
     | 
| 
      
 419 
     | 
    
         
            +
                end
         
     | 
| 
      
 420 
     | 
    
         
            +
              end
         
     | 
| 
      
 421 
     | 
    
         
            +
             
     | 
| 
      
 422 
     | 
    
         
            +
              describe '#update_ipv4' do
         
     | 
| 
      
 423 
     | 
    
         
            +
                # pending 'not necessary'
         
     | 
| 
      
 424 
     | 
    
         
            +
              end
         
     | 
| 
      
 425 
     | 
    
         
            +
             
     | 
| 
      
 426 
     | 
    
         
            +
             
     | 
| 
      
 427 
     | 
    
         
            +
              describe '#update_ips' do
         
     | 
| 
      
 428 
     | 
    
         
            +
                it 'take 1 input as parameter' do
         
     | 
| 
      
 429 
     | 
    
         
            +
                  expect(@gand.update_ips('')).to be_true
         
     | 
| 
      
 430 
     | 
    
         
            +
                end
         
     | 
| 
      
 431 
     | 
    
         
            +
             
     | 
| 
      
 432 
     | 
    
         
            +
                context 'when input is not a String' do
         
     | 
| 
      
 433 
     | 
    
         
            +
                  it 'raise an error' do
         
     | 
| 
      
 434 
     | 
    
         
            +
                    expect{ @gand.update_ips(['1.2.3.4']) }.to raise_error(ArgumentError, /update is not a String/)
         
     | 
| 
      
 435 
     | 
    
         
            +
                  end
         
     | 
| 
      
 436 
     | 
    
         
            +
                end
         
     | 
| 
      
 437 
     | 
    
         
            +
             
     | 
| 
      
 438 
     | 
    
         
            +
                context 'when no ip to update' do
         
     | 
| 
      
 439 
     | 
    
         
            +
                  it 'returns true without doing anything' do
         
     | 
| 
      
 440 
     | 
    
         
            +
                    allow(@gand).to receive(:get_zone_version)
         
     | 
| 
      
 441 
     | 
    
         
            +
                    allow(@gand).to receive(:create_new_zone_version)
         
     | 
| 
      
 442 
     | 
    
         
            +
                    allow(@gand).to receive(:clone_zone_version)
         
     | 
| 
      
 443 
     | 
    
         
            +
             
     | 
| 
      
 444 
     | 
    
         
            +
                    expect(@gand.update_ips('')).to be_true
         
     | 
| 
      
 445 
     | 
    
         
            +
             
     | 
| 
      
 446 
     | 
    
         
            +
                    expect(@gand).to_not have_received(:get_zone_version)
         
     | 
| 
      
 447 
     | 
    
         
            +
                    expect(@gand).to_not have_received(:create_new_zone_version)
         
     | 
| 
      
 448 
     | 
    
         
            +
                    expect(@gand).to_not have_received(:clone_zone_version)
         
     | 
| 
      
 449 
     | 
    
         
            +
                  end
         
     | 
| 
      
 450 
     | 
    
         
            +
             
     | 
| 
      
 451 
     | 
    
         
            +
                  it 'output no update needed' do
         
     | 
| 
      
 452 
     | 
    
         
            +
                    @gand.update_ips('')
         
     | 
| 
      
 453 
     | 
    
         
            +
                    expect(@output.string).to match /no update needed/
         
     | 
| 
      
 454 
     | 
    
         
            +
                  end
         
     | 
| 
      
 455 
     | 
    
         
            +
                end
         
     | 
| 
      
 456 
     | 
    
         
            +
             
     | 
| 
      
 457 
     | 
    
         
            +
                context 'when ipv4 to update' do
         
     | 
| 
      
 458 
     | 
    
         
            +
             
     | 
| 
      
 459 
     | 
    
         
            +
                  it 'updates ipv4 record' do
         
     | 
| 
      
 460 
     | 
    
         
            +
                    expect(@gand).to receive(:update_ipv4).and_return(true)
         
     | 
| 
      
 461 
     | 
    
         
            +
                    @gand.update_ips '1.2.3.4'
         
     | 
| 
      
 462 
     | 
    
         
            +
                  end
         
     | 
| 
      
 463 
     | 
    
         
            +
             
     | 
| 
      
 464 
     | 
    
         
            +
                  context 'when activation of new zone version is OK' do
         
     | 
| 
      
 465 
     | 
    
         
            +
                    it 'returns true' do
         
     | 
| 
      
 466 
     | 
    
         
            +
                      expect(@gand.update_ips('1.2.3.4')).to be_true
         
     | 
| 
      
 467 
     | 
    
         
            +
                    end
         
     | 
| 
      
 468 
     | 
    
         
            +
             
     | 
| 
      
 469 
     | 
    
         
            +
                    it 'output update done' do
         
     | 
| 
      
 470 
     | 
    
         
            +
                      @gand.update_ips('1.2.3.4')
         
     | 
| 
      
 471 
     | 
    
         
            +
                      expect(@output.string).to match /update done/
         
     | 
| 
      
 472 
     | 
    
         
            +
                    end
         
     | 
| 
      
 473 
     | 
    
         
            +
                  end
         
     | 
| 
      
 474 
     | 
    
         
            +
             
     | 
| 
      
 475 
     | 
    
         
            +
                  context 'when activation of new zone version is KO' do
         
     | 
| 
      
 476 
     | 
    
         
            +
                    before :each do
         
     | 
| 
      
 477 
     | 
    
         
            +
                      expect(@gand).to receive(:get_zone_version).and_return([666, [666]])
         
     | 
| 
      
 478 
     | 
    
         
            +
                      expect(@api).to receive(:set).with(anything(), 3).and_return(false)
         
     | 
| 
      
 479 
     | 
    
         
            +
                    end
         
     | 
| 
      
 480 
     | 
    
         
            +
             
     | 
| 
      
 481 
     | 
    
         
            +
                    it 'returns false' do
         
     | 
| 
      
 482 
     | 
    
         
            +
                      expect(@gand.update_ips('1.2.3.4')).to be_false
         
     | 
| 
      
 483 
     | 
    
         
            +
                    end
         
     | 
| 
      
 484 
     | 
    
         
            +
             
     | 
| 
      
 485 
     | 
    
         
            +
                    it 'output update FAILED' do
         
     | 
| 
      
 486 
     | 
    
         
            +
                      @gand.update_ips('1.2.3.4')
         
     | 
| 
      
 487 
     | 
    
         
            +
                      expect(@output.string).to match /update FAILED/
         
     | 
| 
      
 488 
     | 
    
         
            +
                    end
         
     | 
| 
      
 489 
     | 
    
         
            +
                  end
         
     | 
| 
      
 490 
     | 
    
         
            +
             
     | 
| 
      
 491 
     | 
    
         
            +
                  it 'activate the new zone version' do
         
     | 
| 
      
 492 
     | 
    
         
            +
                    expect(@gand).to receive(:activate_updated_version).and_return(true)
         
     | 
| 
      
 493 
     | 
    
         
            +
                    @gand.update_ips '1.2.3.4'
         
     | 
| 
      
 494 
     | 
    
         
            +
                  end
         
     | 
| 
      
 495 
     | 
    
         
            +
                end
         
     | 
| 
      
 496 
     | 
    
         
            +
             
     | 
| 
      
 497 
     | 
    
         
            +
                context 'when only 1 zone version exists' do
         
     | 
| 
      
 498 
     | 
    
         
            +
                  it 'creates a new version for the zone from current active version' do
         
     | 
| 
      
 499 
     | 
    
         
            +
                    allow(@gand).to receive(:clone_zone_version)
         
     | 
| 
      
 500 
     | 
    
         
            +
                    mash = Hashie::Mash.new({:version => 1, :versions => [1]})
         
     | 
| 
      
 501 
     | 
    
         
            +
                    allow(@api).to receive(:info).and_return(mash)
         
     | 
| 
      
 502 
     | 
    
         
            +
                    expect(@api).to receive(:new_version).and_return(99)
         
     | 
| 
      
 503 
     | 
    
         
            +
             
     | 
| 
      
 504 
     | 
    
         
            +
                    @gand.update_ips('1.2.3.4')
         
     | 
| 
      
 505 
     | 
    
         
            +
             
     | 
| 
      
 506 
     | 
    
         
            +
                    expect(@gand).to_not receive(:clone_zone_version)
         
     | 
| 
      
 507 
     | 
    
         
            +
                  end
         
     | 
| 
      
 508 
     | 
    
         
            +
                end
         
     | 
| 
      
 509 
     | 
    
         
            +
             
     | 
| 
      
 510 
     | 
    
         
            +
                context 'when more than 1 zone version exist' do
         
     | 
| 
      
 511 
     | 
    
         
            +
                  it 'clone the last non active version of the zone' do
         
     | 
| 
      
 512 
     | 
    
         
            +
                    expect(@gand).to receive(:clone_zone_version)
         
     | 
| 
      
 513 
     | 
    
         
            +
                    @gand.update_ips('1.2.3.4')
         
     | 
| 
      
 514 
     | 
    
         
            +
                    expect(@api).to_not receive(:new_version)
         
     | 
| 
      
 515 
     | 
    
         
            +
                  end
         
     | 
| 
      
 516 
     | 
    
         
            +
                end
         
     | 
| 
      
 517 
     | 
    
         
            +
              end
         
     | 
| 
      
 518 
     | 
    
         
            +
             
     | 
| 
      
 519 
     | 
    
         
            +
              describe '#ipv4_available' do
         
     | 
| 
      
 520 
     | 
    
         
            +
                context 'when network is not available' do
         
     | 
| 
      
 521 
     | 
    
         
            +
                  before :each do
         
     | 
| 
      
 522 
     | 
    
         
            +
                    allow(@gand).to receive(:system).and_return(false)
         
     | 
| 
      
 523 
     | 
    
         
            +
                  end
         
     | 
| 
      
 524 
     | 
    
         
            +
             
     | 
| 
      
 525 
     | 
    
         
            +
                  it 'returns false' do
         
     | 
| 
      
 526 
     | 
    
         
            +
                    expect(@gand.ipv4_available?).to be false
         
     | 
| 
      
 527 
     | 
    
         
            +
                  end
         
     | 
| 
      
 528 
     | 
    
         
            +
             
     | 
| 
      
 529 
     | 
    
         
            +
                  it 'output IPv4 network not available' do
         
     | 
| 
      
 530 
     | 
    
         
            +
                    @gand.ipv4_available?
         
     | 
| 
      
 531 
     | 
    
         
            +
                    expect(@output.string).to match /IPv4 network not available/
         
     | 
| 
      
 532 
     | 
    
         
            +
                  end
         
     | 
| 
      
 533 
     | 
    
         
            +
                end
         
     | 
| 
      
 534 
     | 
    
         
            +
             
     | 
| 
      
 535 
     | 
    
         
            +
                context 'when network is available' do
         
     | 
| 
      
 536 
     | 
    
         
            +
                  it 'returns true' do
         
     | 
| 
      
 537 
     | 
    
         
            +
                    expect(@gand.ipv4_available?).to be true
         
     | 
| 
      
 538 
     | 
    
         
            +
                  end
         
     | 
| 
      
 539 
     | 
    
         
            +
             
     | 
| 
      
 540 
     | 
    
         
            +
                  it 'output IPv4 network available' do
         
     | 
| 
      
 541 
     | 
    
         
            +
                    @gand.ipv4_available?
         
     | 
| 
      
 542 
     | 
    
         
            +
                    expect(@output.string).to match /IPv4 network available/
         
     | 
| 
      
 543 
     | 
    
         
            +
                  end
         
     | 
| 
      
 544 
     | 
    
         
            +
                end
         
     | 
| 
      
 545 
     | 
    
         
            +
             
     | 
| 
      
 546 
     | 
    
         
            +
                context 'on windows platform' do
         
     | 
| 
      
 547 
     | 
    
         
            +
                  it 'redirect output to > NUL' do
         
     | 
| 
      
 548 
     | 
    
         
            +
                    pending
         
     | 
| 
      
 549 
     | 
    
         
            +
                  end
         
     | 
| 
      
 550 
     | 
    
         
            +
                end
         
     | 
| 
      
 551 
     | 
    
         
            +
             
     | 
| 
      
 552 
     | 
    
         
            +
                context 'on Linux platform' do
         
     | 
| 
      
 553 
     | 
    
         
            +
                  it 'redirect output to > /dev/null 2>&1' do
         
     | 
| 
      
 554 
     | 
    
         
            +
                    pending
         
     | 
| 
      
 555 
     | 
    
         
            +
                  end
         
     | 
| 
      
 556 
     | 
    
         
            +
                end
         
     | 
| 
      
 557 
     | 
    
         
            +
              end
         
     | 
| 
      
 558 
     | 
    
         
            +
             
     | 
| 
      
 559 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,81 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'ganddyn'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe Ganddyn::IpResolver do
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              before :each do
         
     | 
| 
      
 8 
     | 
    
         
            +
                @ip = Ganddyn::IpResolver.new( { :ipv4 => 'http://v4.rspec.domain.com', :ipv6 => 'http://v6.rspec.domain.com' } )
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              context '#intialize' do
         
     | 
| 
      
 12 
     | 
    
         
            +
                it 'takes 0 parameter' do
         
     | 
| 
      
 13 
     | 
    
         
            +
                  Ganddyn::IpResolver.new.should be_a Ganddyn::IpResolver
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                it 'take 1 parameter' do
         
     | 
| 
      
 17 
     | 
    
         
            +
                  Ganddyn::IpResolver.new({}).should be_a Ganddyn::IpResolver
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                it 'raises an error if parameter is not Hash' do
         
     | 
| 
      
 21 
     | 
    
         
            +
                  expect { Ganddyn::IpResolver.new([]) }.to raise_error(ArgumentError, /urls is not a Hash/)
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              context '#get_ipv4' do
         
     | 
| 
      
 26 
     | 
    
         
            +
                it 'returns the ipv4' do  
         
     | 
| 
      
 27 
     | 
    
         
            +
                  stub_request(:get, 'v4.rspec.domain.com').to_return(:body => '1.2.3.4', :status => 200, :headers => { 'Content-Length' => 3 })
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @ip.get_ipv4.should == '1.2.3.4'
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                it 'returns empty string if client has no ipv4' do
         
     | 
| 
      
 32 
     | 
    
         
            +
                  stub_request(:get, 'v4.rspec.domain.com').to_raise(Exception)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @ip.get_ipv4.should be_nil
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                it 'returns nil if server is not reachable' do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  stub_request(:get, 'v4.rspec.domain.com').to_raise(SocketError)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @ip.get_ipv4.should be_nil
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                it 'returns nil if url is incorrect' do
         
     | 
| 
      
 42 
     | 
    
         
            +
                  stub_request(:get, 'v4.rspec.domain.com').to_return(:body => '<html><head>
         
     | 
| 
      
 43 
     | 
    
         
            +
            <title>404 Not Found</title>
         
     | 
| 
      
 44 
     | 
    
         
            +
            </head><body>
         
     | 
| 
      
 45 
     | 
    
         
            +
            <h1>Not Found</h1>
         
     | 
| 
      
 46 
     | 
    
         
            +
            <p>The requested URL xxx was not found on this server.</p>
         
     | 
| 
      
 47 
     | 
    
         
            +
            <hr>
         
     | 
| 
      
 48 
     | 
    
         
            +
            </body></html>', :status => 404, :headers => { 'Content-Length' => 3 })
         
     | 
| 
      
 49 
     | 
    
         
            +
                  @ip.get_ipv4.should be_nil
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              context '#get_ipv6' do
         
     | 
| 
      
 54 
     | 
    
         
            +
                it 'returns the ipv6' do
         
     | 
| 
      
 55 
     | 
    
         
            +
                  stub_request(:get, 'v6.rspec.domain.com').to_return(:body => '3b12:d24:1e6a:8e81:b6a2:6f67:5627:bf44', :status => 200, :headers => { 'Content-Length' => 3 })
         
     | 
| 
      
 56 
     | 
    
         
            +
                  @ip.get_ipv6.should == '3b12:d24:1e6a:8e81:b6a2:6f67:5627:bf44'
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                it 'returns nil if client has no ipv6' do
         
     | 
| 
      
 60 
     | 
    
         
            +
                  stub_request(:get, 'v6.rspec.domain.com').to_raise(Exception)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  @ip.get_ipv6.should be_nil
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                it 'returns nil if server is not reachable' do
         
     | 
| 
      
 66 
     | 
    
         
            +
                  stub_request(:get, 'v6.rspec.domain.com').to_raise(SocketError)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  @ip.get_ipv6.should be_nil
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                it 'returns nil if url is incorrect' do
         
     | 
| 
      
 71 
     | 
    
         
            +
                  stub_request(:get, 'v6.rspec.domain.com').to_return(:body => '<html><head>
         
     | 
| 
      
 72 
     | 
    
         
            +
            <title>404 Not Found</title>
         
     | 
| 
      
 73 
     | 
    
         
            +
            </head><body>
         
     | 
| 
      
 74 
     | 
    
         
            +
            <h1>Not Found</h1>
         
     | 
| 
      
 75 
     | 
    
         
            +
            <p>The requested URL xxx was not found on this server.</p>
         
     | 
| 
      
 76 
     | 
    
         
            +
            <hr>
         
     | 
| 
      
 77 
     | 
    
         
            +
            </body></html>', :status => 404, :headers => { 'Content-Length' => 3 })
         
     | 
| 
      
 78 
     | 
    
         
            +
                  @ip.get_ipv6.should be_nil
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
              end
         
     | 
| 
      
 81 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # This file was generated by the `rspec --init` command. Conventionally, all
         
     | 
| 
      
 2 
     | 
    
         
            +
            # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Require this file using `require "spec_helper"` to ensure that it is only
         
     | 
| 
      
 4 
     | 
    
         
            +
            # loaded once.
         
     | 
| 
      
 5 
     | 
    
         
            +
            #
         
     | 
| 
      
 6 
     | 
    
         
            +
            # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
         
     | 
| 
      
 7 
     | 
    
         
            +
            RSpec.configure do |config|
         
     | 
| 
      
 8 
     | 
    
         
            +
              config.treat_symbols_as_metadata_keys_with_true_values = true
         
     | 
| 
      
 9 
     | 
    
         
            +
              config.run_all_when_everything_filtered = true
         
     | 
| 
      
 10 
     | 
    
         
            +
              config.filter_run :focus
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              # Run specs in random order to surface order dependencies. If you find an
         
     | 
| 
      
 13 
     | 
    
         
            +
              # order dependency and want to debug it, you can fix the order by providing
         
     | 
| 
      
 14 
     | 
    
         
            +
              # the seed, which is printed after each run.
         
     | 
| 
      
 15 
     | 
    
         
            +
              #     --seed 1234
         
     | 
| 
      
 16 
     | 
    
         
            +
              config.order = 'random'
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            require 'webmock/rspec'
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            # enable to test private method of a class
         
     | 
| 
      
 22 
     | 
    
         
            +
            def describe_internally *args, &block
         
     | 
| 
      
 23 
     | 
    
         
            +
              example = describe *args, &block
         
     | 
| 
      
 24 
     | 
    
         
            +
              cur_class = args[0]
         
     | 
| 
      
 25 
     | 
    
         
            +
              if cur_class.is_a? Class
         
     | 
| 
      
 26 
     | 
    
         
            +
                saved_private_instance_methods = cur_class.private_instance_methods
         
     | 
| 
      
 27 
     | 
    
         
            +
                example.before do
         
     | 
| 
      
 28 
     | 
    
         
            +
                  cur_class.class_eval { public *saved_private_instance_methods }
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
                example.after do
         
     | 
| 
      
 31 
     | 
    
         
            +
                  cur_class.class_eval { private *saved_private_instance_methods }
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,166 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: ganddyn
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.0.1
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Guillaume Virlet
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2014-05-23 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 13 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: bundler
         
     | 
| 
      
 15 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 16 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '1.3'
         
     | 
| 
      
 20 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 21 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 22 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 23 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 24 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '1.3'
         
     | 
| 
      
 27 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 28 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 29 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 30 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 31 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 32 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 33 
     | 
    
         
            +
                    version: 10.3.1
         
     | 
| 
      
 34 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 35 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 36 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 37 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 38 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 39 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 40 
     | 
    
         
            +
                    version: 10.3.1
         
     | 
| 
      
 41 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 42 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 43 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 44 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 45 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 46 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 47 
     | 
    
         
            +
                    version: 2.14.1
         
     | 
| 
      
 48 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 49 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 50 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 51 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 52 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 53 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 54 
     | 
    
         
            +
                    version: 2.14.1
         
     | 
| 
      
 55 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 56 
     | 
    
         
            +
              name: webmock
         
     | 
| 
      
 57 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 58 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 59 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 60 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 61 
     | 
    
         
            +
                    version: 1.17.4
         
     | 
| 
      
 62 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 63 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 64 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 65 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 66 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 67 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 68 
     | 
    
         
            +
                    version: 1.17.4
         
     | 
| 
      
 69 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 70 
     | 
    
         
            +
              name: gandi
         
     | 
| 
      
 71 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 72 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 73 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 74 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 75 
     | 
    
         
            +
                    version: 2.0.10
         
     | 
| 
      
 76 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 77 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 78 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 79 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 80 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 81 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 82 
     | 
    
         
            +
                    version: 2.0.10
         
     | 
| 
      
 83 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 84 
     | 
    
         
            +
              name: highline
         
     | 
| 
      
 85 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 86 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 87 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 88 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 89 
     | 
    
         
            +
                    version: 1.6.21
         
     | 
| 
      
 90 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 91 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 92 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 93 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 94 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 95 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 96 
     | 
    
         
            +
                    version: 1.6.21
         
     | 
| 
      
 97 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 98 
     | 
    
         
            +
              name: certified
         
     | 
| 
      
 99 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 100 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 101 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 102 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 103 
     | 
    
         
            +
                    version: 0.1.2
         
     | 
| 
      
 104 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 105 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 106 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 107 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 108 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 109 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 110 
     | 
    
         
            +
                    version: 0.1.2
         
     | 
| 
      
 111 
     | 
    
         
            +
            description: |-
         
     | 
| 
      
 112 
     | 
    
         
            +
              This gem allows to update your GANDI DNS zone with the current external IPv4 of your machine.
         
     | 
| 
      
 113 
     | 
    
         
            +
              It duplicate current zone information in the last inactive version of the zone (or a newly
         
     | 
| 
      
 114 
     | 
    
         
            +
              created one if only one version exist). It updates the IPv4 for the name requested and activate
         
     | 
| 
      
 115 
     | 
    
         
            +
              this version.
         
     | 
| 
      
 116 
     | 
    
         
            +
            email:
         
     | 
| 
      
 117 
     | 
    
         
            +
            - github@virlet.org
         
     | 
| 
      
 118 
     | 
    
         
            +
            executables:
         
     | 
| 
      
 119 
     | 
    
         
            +
            - ganddyn
         
     | 
| 
      
 120 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 121 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 122 
     | 
    
         
            +
            files:
         
     | 
| 
      
 123 
     | 
    
         
            +
            - .gitignore
         
     | 
| 
      
 124 
     | 
    
         
            +
            - .rspec
         
     | 
| 
      
 125 
     | 
    
         
            +
            - .travis.yml
         
     | 
| 
      
 126 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 127 
     | 
    
         
            +
            - LICENSE.txt
         
     | 
| 
      
 128 
     | 
    
         
            +
            - README.md
         
     | 
| 
      
 129 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 130 
     | 
    
         
            +
            - bin/ganddyn
         
     | 
| 
      
 131 
     | 
    
         
            +
            - ganddyn.gemspec
         
     | 
| 
      
 132 
     | 
    
         
            +
            - lib/ganddyn.rb
         
     | 
| 
      
 133 
     | 
    
         
            +
            - lib/ganddyn/client.rb
         
     | 
| 
      
 134 
     | 
    
         
            +
            - lib/ganddyn/ipresolver.rb
         
     | 
| 
      
 135 
     | 
    
         
            +
            - lib/ganddyn/version.rb
         
     | 
| 
      
 136 
     | 
    
         
            +
            - spec/lib/ganddyn/client_spec.rb
         
     | 
| 
      
 137 
     | 
    
         
            +
            - spec/lib/ganddyn/ipresolver_spec.rb
         
     | 
| 
      
 138 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
      
 139 
     | 
    
         
            +
            homepage: https://github.com/doc75/ganddyn
         
     | 
| 
      
 140 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 141 
     | 
    
         
            +
            - MIT
         
     | 
| 
      
 142 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 143 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 144 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 145 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 146 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 147 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 148 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 149 
     | 
    
         
            +
              - - '>='
         
     | 
| 
      
 150 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 151 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 152 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 153 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 154 
     | 
    
         
            +
              - - '>='
         
     | 
| 
      
 155 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 156 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 157 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 158 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 159 
     | 
    
         
            +
            rubygems_version: 2.1.9
         
     | 
| 
      
 160 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 161 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 162 
     | 
    
         
            +
            summary: Update GANDI DNS zone IPv4
         
     | 
| 
      
 163 
     | 
    
         
            +
            test_files:
         
     | 
| 
      
 164 
     | 
    
         
            +
            - spec/lib/ganddyn/client_spec.rb
         
     | 
| 
      
 165 
     | 
    
         
            +
            - spec/lib/ganddyn/ipresolver_spec.rb
         
     | 
| 
      
 166 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     |