kitchen-nodes-fqdn 0.4.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/.rubocop.yml +2 -0
 - data/.travis.yml +11 -0
 - data/CHANGELOG.md +3 -0
 - data/Gemfile +3 -0
 - data/LICENSE +15 -0
 - data/README.md +142 -0
 - data/Rakefile +11 -0
 - data/kitchen-nodes.gemspec +30 -0
 - data/lib/kitchen/provisioner/ip_finder.rb +18 -0
 - data/lib/kitchen/provisioner/ip_finder/ssh.rb +97 -0
 - data/lib/kitchen/provisioner/ip_finder/winrm.rb +35 -0
 - data/lib/kitchen/provisioner/nodes.rb +110 -0
 - data/lib/kitchen/provisioner/nodes_version.rb +24 -0
 - data/spec/unit/nodes_spec.rb +210 -0
 - data/spec/unit/stubs/ifconfig.txt +36 -0
 - data/spec/unit/stubs/ip.txt +15 -0
 - metadata +178 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: d0f9f88c511094a729079500e92c7d9dfe693977
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 6d1f9c7880fceb77c8ac872b727f9edd6e65a7be
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: e5d82650f62fad201c711b1d858487428ef1861c493d41b1002918799192c850ea1c662c469dd55cc48161e8d54eaa7f4d0c8a0a42bbb3811105fc5f53a58399
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 2c12c15d84dbbbfa19db155f09f605278e758cc7cfa1f40ac9f3bc73769ea21baf56251de0c723417f0b7712402fa8542c53e36333514f2a085c177dda3dc745
         
     | 
    
        data/.gitignore
    ADDED
    
    
    
        data/.rubocop.yml
    ADDED
    
    
    
        data/.travis.yml
    ADDED
    
    
    
        data/CHANGELOG.md
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Author:: Matt Wrock (<matt@mattwrock.com>)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Copyright (C) 2015, Matt Wrock
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
      
 6 
     | 
    
         
            +
            you may not use this file except in compliance with the License.
         
     | 
| 
      
 7 
     | 
    
         
            +
            You may obtain a copy of the License at
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
               http://www.apache.org/licenses/LICENSE-2.0
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Unless required by applicable law or agreed to in writing, software
         
     | 
| 
      
 12 
     | 
    
         
            +
            distributed under the License is distributed on an "AS IS" BASIS,
         
     | 
| 
      
 13 
     | 
    
         
            +
            WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         
     | 
| 
      
 14 
     | 
    
         
            +
            See the License for the specific language governing permissions and
         
     | 
| 
      
 15 
     | 
    
         
            +
            limitations under the License.
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,142 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # <a name="title"></a> Kitchen::Nodes
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            A Test Kitchen Provisioner that generates searchable Nodes.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            The nodes provisioner extends the `chef-zero` provisioner along with all of its functionality and configuration. `chef-zero` can support chef searches by querying against node data stored in json files inside of the kitchen `nodes` folder. The `kitchen-nodes` plugin automatically generates a node file when a test instance is provisioned by test-kitchen.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ### Example nodes:
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ```
         
     | 
| 
      
 10 
     | 
    
         
            +
            {
         
     | 
| 
      
 11 
     | 
    
         
            +
              "id": "server-community-ubuntu-1204",
         
     | 
| 
      
 12 
     | 
    
         
            +
              "automatic": {
         
     | 
| 
      
 13 
     | 
    
         
            +
                "ipaddress": "172.17.0.8",
         
     | 
| 
      
 14 
     | 
    
         
            +
                "platform": "ubuntu"
         
     | 
| 
      
 15 
     | 
    
         
            +
              },
         
     | 
| 
      
 16 
     | 
    
         
            +
              "normal": {
         
     | 
| 
      
 17 
     | 
    
         
            +
                "attr1": "val1"
         
     | 
| 
      
 18 
     | 
    
         
            +
              }
         
     | 
| 
      
 19 
     | 
    
         
            +
              "run_list": [
         
     | 
| 
      
 20 
     | 
    
         
            +
                "recipe[apt]",
         
     | 
| 
      
 21 
     | 
    
         
            +
                "recipe[couchbase-tests::ipaddress]",
         
     | 
| 
      
 22 
     | 
    
         
            +
                "recipe[couchbase::server]",
         
     | 
| 
      
 23 
     | 
    
         
            +
                "recipe[export-node]"
         
     | 
| 
      
 24 
     | 
    
         
            +
              ]
         
     | 
| 
      
 25 
     | 
    
         
            +
            }
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            {
         
     | 
| 
      
 28 
     | 
    
         
            +
              "id": "second-node-ubuntu-1204",
         
     | 
| 
      
 29 
     | 
    
         
            +
              "automatic": {
         
     | 
| 
      
 30 
     | 
    
         
            +
                "ipaddress": "172.17.0.9",
         
     | 
| 
      
 31 
     | 
    
         
            +
                "platform": "ubuntu"
         
     | 
| 
      
 32 
     | 
    
         
            +
              },
         
     | 
| 
      
 33 
     | 
    
         
            +
              "run_list": [
         
     | 
| 
      
 34 
     | 
    
         
            +
                "recipe[apt]",
         
     | 
| 
      
 35 
     | 
    
         
            +
                "recipe[couchbase-tests::ipaddress]",
         
     | 
| 
      
 36 
     | 
    
         
            +
                "recipe[couchbase-tests::default]",
         
     | 
| 
      
 37 
     | 
    
         
            +
                "recipe[export-node]"
         
     | 
| 
      
 38 
     | 
    
         
            +
              ]
         
     | 
| 
      
 39 
     | 
    
         
            +
            }
         
     | 
| 
      
 40 
     | 
    
         
            +
            ```
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            The node data includes the node id based on the test-kitchen suite name, the run list assigned to the node, the normal attributes included in the `.kitchen.yml` file, the externally reachable ip address and the platform of the test instance os.
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            ## <a name="installation"></a> Installation
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            ```
         
     | 
| 
      
 47 
     | 
    
         
            +
            gem install kitchen-nodes
         
     | 
| 
      
 48 
     | 
    
         
            +
            ```
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            ## <a name="config"></a> Configuration
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            Use `nodes` instead of `chef-zero` for the kitchen provisioner name.
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            ```
         
     | 
| 
      
 55 
     | 
    
         
            +
            provisioner:
         
     | 
| 
      
 56 
     | 
    
         
            +
              name: nodes
         
     | 
| 
      
 57 
     | 
    
         
            +
            ```
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            ## <a name="Usage"></a> Usage
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            Using `kitchen-nodes` one can expect all previously converged nodes to be represented in a node file and be searchable. For example consider this scenario looking for a primary node in a cluster in order to add a node to join:
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            ```
         
     | 
| 
      
 64 
     | 
    
         
            +
            require 'timeout'
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            def search_for_nodes(query, timeout = 120)
         
     | 
| 
      
 67 
     | 
    
         
            +
              nodes = []
         
     | 
| 
      
 68 
     | 
    
         
            +
              Timeout::timeout(timeout) do
         
     | 
| 
      
 69 
     | 
    
         
            +
                nodes = search(:node, query)
         
     | 
| 
      
 70 
     | 
    
         
            +
                until  nodes.count > 0 && nodes[0].has_key?('ipaddress')
         
     | 
| 
      
 71 
     | 
    
         
            +
                  sleep 5
         
     | 
| 
      
 72 
     | 
    
         
            +
                  nodes = search(:node, query)
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              if nodes.count == 0 || !nodes[0].has_key?('ipaddress')
         
     | 
| 
      
 77 
     | 
    
         
            +
                raise "Unable to find nodes!"
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
              nodes
         
     | 
| 
      
 81 
     | 
    
         
            +
            end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            primary = search_for_nodes("run_list:*couchbase??server* AND platform:#{node['platform']}")
         
     | 
| 
      
 84 
     | 
    
         
            +
            node.normal["couchbase-tests"]["primary_ip"] = primary[0]['ipaddress']
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            ```
         
     | 
| 
      
 87 
     | 
    
         
            +
            ### <a name="vagrant"></a> Using with Vagrant
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            When using kitchen-nodes with the vagrant driver, make sure you add the following to your `driver_config`:
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            ```
         
     | 
| 
      
 92 
     | 
    
         
            +
            network:
         
     | 
| 
      
 93 
     | 
    
         
            +
              - ["private_network", { type: "dhcp" }]
         
     | 
| 
      
 94 
     | 
    
         
            +
            ```
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            This will add an additional non-NAT NIC to your vagrant box with an IP reachable from the host and other test nodes.
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            ### <a name="virtualbox"></a> Why is my ohai `ipaddress` different from my node ipaddress on vagrant with VirtualBox?
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            Ohai will pick up the localhost ipaddress on vagrant boxes using virtualbox. To reset the `node["ipaddress"]` to the reachable ip, add `hurry-up-and-test::set_non_nat_vbox_ip` to the top of your `run_list`. 
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            ```
         
     | 
| 
      
 103 
     | 
    
         
            +
            suites:
         
     | 
| 
      
 104 
     | 
    
         
            +
              - name: my-suite
         
     | 
| 
      
 105 
     | 
    
         
            +
                run_list:
         
     | 
| 
      
 106 
     | 
    
         
            +
                  - recipe[hurry-up-and-test::set_non_nat_vbox_ip]
         
     | 
| 
      
 107 
     | 
    
         
            +
                  - recipe[cookbook-under-test]
         
     | 
| 
      
 108 
     | 
    
         
            +
            ```
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            You can add this even if you do not use virtualbox and the recipe will do nothing.
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            ## <a name="development"></a> Development
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            * Source hosted at [GitHub][repo]
         
     | 
| 
      
 116 
     | 
    
         
            +
            * Report issues/questions/feature requests on [GitHub Issues][issues]
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            Pull requests are very welcome! Make sure your patches are well tested.
         
     | 
| 
      
 119 
     | 
    
         
            +
            Ideally create a topic branch for every separate change you make. For
         
     | 
| 
      
 120 
     | 
    
         
            +
            example:
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
            1. Fork the repo
         
     | 
| 
      
 123 
     | 
    
         
            +
            2. Create your feature branch (`git checkout -b my-new-feature`)
         
     | 
| 
      
 124 
     | 
    
         
            +
            3. Commit your changes (`git commit -am 'Added some feature'`)
         
     | 
| 
      
 125 
     | 
    
         
            +
            4. Push to the branch (`git push origin my-new-feature`)
         
     | 
| 
      
 126 
     | 
    
         
            +
            5. Create new Pull Request
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            ## <a name="authors"></a> Authors
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
            Created and maintained by [Matt Wrock][author] (<matt@mattwrock.com>)
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
            ## <a name="license"></a> License
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            Apache 2.0 (see [LICENSE][license])
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
            [author]:           https://github.com/mwrock
         
     | 
| 
      
 138 
     | 
    
         
            +
            [issues]:           https://github.com/mwrock/kitchen-nodes/issues
         
     | 
| 
      
 139 
     | 
    
         
            +
            [license]:          https://github.com/mwrock/kitchen-nodes/blob/master/LICENSE
         
     | 
| 
      
 140 
     | 
    
         
            +
            [repo]:             https://github.com/mwrock/kitchen-nodes
         
     | 
| 
      
 141 
     | 
    
         
            +
            [driver_usage]:     http://docs.kitchen-ci.org/drivers/usage
         
     | 
| 
      
 142 
     | 
    
         
            +
            [chef_omnibus_dl]:  http://www.getchef.com/chef/install/
         
     | 
    
        data/Rakefile
    ADDED
    
    
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # coding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            lib = File.expand_path('../lib', __FILE__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'kitchen/provisioner/nodes_version'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Gem::Specification.new do |spec|
         
     | 
| 
      
 7 
     | 
    
         
            +
              spec.name          = 'kitchen-nodes-fqdn'
         
     | 
| 
      
 8 
     | 
    
         
            +
              spec.version       = Kitchen::Provisioner::NODES_VERSION
         
     | 
| 
      
 9 
     | 
    
         
            +
              spec.authors       = ['Matt Wrock', 'Marcin Cabaj']
         
     | 
| 
      
 10 
     | 
    
         
            +
              spec.email         = ['matt@mattwrock.com', 'mcabaj@gmail.com']
         
     | 
| 
      
 11 
     | 
    
         
            +
              spec.description   = 'A Test Kitchen Provisioner for Chef Nodes'
         
     | 
| 
      
 12 
     | 
    
         
            +
              spec.summary       = spec.description
         
     | 
| 
      
 13 
     | 
    
         
            +
              spec.homepage      = ''
         
     | 
| 
      
 14 
     | 
    
         
            +
              spec.license       = 'Apache 2.0'
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              spec.files         = `git ls-files -z`.split("\x0")
         
     | 
| 
      
 17 
     | 
    
         
            +
              spec.executables   = []
         
     | 
| 
      
 18 
     | 
    
         
            +
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         
     | 
| 
      
 19 
     | 
    
         
            +
              spec.require_paths = ['lib']
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              spec.add_dependency 'net-ping'
         
     | 
| 
      
 22 
     | 
    
         
            +
              spec.add_dependency 'win32-security'
         
     | 
| 
      
 23 
     | 
    
         
            +
              spec.add_dependency 'test-kitchen', '~> 1.4'
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              spec.add_development_dependency 'bundler', '~> 1.3'
         
     | 
| 
      
 26 
     | 
    
         
            +
              spec.add_development_dependency 'fakefs', '~> 0.4'
         
     | 
| 
      
 27 
     | 
    
         
            +
              spec.add_development_dependency 'rake'
         
     | 
| 
      
 28 
     | 
    
         
            +
              spec.add_development_dependency 'rspec', '~> 3.2'
         
     | 
| 
      
 29 
     | 
    
         
            +
              spec.add_development_dependency 'rubocop', '~> 0.29'
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Kitchen
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Provisioner
         
     | 
| 
      
 3 
     | 
    
         
            +
                # Locates active IPs that are not localhost
         
     | 
| 
      
 4 
     | 
    
         
            +
                # there are separate implementations for
         
     | 
| 
      
 5 
     | 
    
         
            +
                # different kitchen transports
         
     | 
| 
      
 6 
     | 
    
         
            +
                module IpFinder
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def self.for_transport(transport, state)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    transport_string = transport.class.name.split('::').last
         
     | 
| 
      
 9 
     | 
    
         
            +
                    require("kitchen/provisioner/ip_finder/#{transport_string.downcase}")
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    connection = transport.connection(state)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    klass = const_get(transport_string)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    object = klass.new(connection)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    object
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,97 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Kitchen
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Transport
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Ssh < Kitchen::Transport::Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  # Monkey patch of test-kitchen ssh transport
         
     | 
| 
      
 5 
     | 
    
         
            +
                  # that returns stdout
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class Connection < Kitchen::Transport::Base::Connection
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def node_execute(command, &block)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      return if command.nil?
         
     | 
| 
      
 9 
     | 
    
         
            +
                      out, exit_code = node_execute_with_exit_code(command, &block)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                      if exit_code != 0
         
     | 
| 
      
 12 
     | 
    
         
            +
                        fail Transport::SshFailed,
         
     | 
| 
      
 13 
     | 
    
         
            +
                             "SSH exited (#{exit_code}) for command: [#{command}]"
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                      out
         
     | 
| 
      
 16 
     | 
    
         
            +
                    rescue Net::SSH::Exception => ex
         
     | 
| 
      
 17 
     | 
    
         
            +
                      raise SshFailed, "SSH command failed (#{ex.message})"
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    # rubocop:disable Metrics/AbcSize
         
     | 
| 
      
 21 
     | 
    
         
            +
                    def node_execute_with_exit_code(command)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      exit_code = nil
         
     | 
| 
      
 23 
     | 
    
         
            +
                      out = []
         
     | 
| 
      
 24 
     | 
    
         
            +
                      session.open_channel do |channel|
         
     | 
| 
      
 25 
     | 
    
         
            +
                        channel.request_pty
         
     | 
| 
      
 26 
     | 
    
         
            +
                        channel.exec(command) do |_ch, _success|
         
     | 
| 
      
 27 
     | 
    
         
            +
                          channel.on_data do |_ch, data|
         
     | 
| 
      
 28 
     | 
    
         
            +
                            out << data
         
     | 
| 
      
 29 
     | 
    
         
            +
                            yield data if block_given?
         
     | 
| 
      
 30 
     | 
    
         
            +
                          end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                          channel.on_extended_data do |_ch, _type, data|
         
     | 
| 
      
 33 
     | 
    
         
            +
                            out << data
         
     | 
| 
      
 34 
     | 
    
         
            +
                            yield data if block_given?
         
     | 
| 
      
 35 
     | 
    
         
            +
                          end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                          channel.on_request('exit-status') do |_ch, data|
         
     | 
| 
      
 38 
     | 
    
         
            +
                            exit_code = data.read_long
         
     | 
| 
      
 39 
     | 
    
         
            +
                          end
         
     | 
| 
      
 40 
     | 
    
         
            +
                        end
         
     | 
| 
      
 41 
     | 
    
         
            +
                      end
         
     | 
| 
      
 42 
     | 
    
         
            +
                      session.loop
         
     | 
| 
      
 43 
     | 
    
         
            +
                      [out.join("\n"), exit_code]
         
     | 
| 
      
 44 
     | 
    
         
            +
                    end
         
     | 
| 
      
 45 
     | 
    
         
            +
                    # rubocop:enable Metrics/AbcSize
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              module Provisioner
         
     | 
| 
      
 51 
     | 
    
         
            +
                module IpFinder
         
     | 
| 
      
 52 
     | 
    
         
            +
                  # SSH implementation for returning active non-localhost IPs
         
     | 
| 
      
 53 
     | 
    
         
            +
                  class Ssh
         
     | 
| 
      
 54 
     | 
    
         
            +
                    IP4REGEX = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/
         
     | 
| 
      
 55 
     | 
    
         
            +
                    def initialize(connection)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      @connection = connection
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    def find_ips
         
     | 
| 
      
 60 
     | 
    
         
            +
                      ips = []
         
     | 
| 
      
 61 
     | 
    
         
            +
                      (0..5).each do
         
     | 
| 
      
 62 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 63 
     | 
    
         
            +
                          ips = run_ifconfig
         
     | 
| 
      
 64 
     | 
    
         
            +
                        rescue Kitchen::Transport::TransportFailed
         
     | 
| 
      
 65 
     | 
    
         
            +
                          ips = run_ip_addr
         
     | 
| 
      
 66 
     | 
    
         
            +
                        end
         
     | 
| 
      
 67 
     | 
    
         
            +
                        return ips unless ips.empty?
         
     | 
| 
      
 68 
     | 
    
         
            +
                        sleep 0.5
         
     | 
| 
      
 69 
     | 
    
         
            +
                      end
         
     | 
| 
      
 70 
     | 
    
         
            +
                      ips
         
     | 
| 
      
 71 
     | 
    
         
            +
                    end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                    def run_ifconfig
         
     | 
| 
      
 74 
     | 
    
         
            +
                      response = @connection.node_execute('/sbin/ifconfig -a')
         
     | 
| 
      
 75 
     | 
    
         
            +
                      ips = []
         
     | 
| 
      
 76 
     | 
    
         
            +
                      response.split(/^\S+/).each do |device|
         
     | 
| 
      
 77 
     | 
    
         
            +
                        next if !device.include?('RUNNING') || device.include?('LOOPBACK')
         
     | 
| 
      
 78 
     | 
    
         
            +
                        ips << IP4REGEX.match(device)[1]
         
     | 
| 
      
 79 
     | 
    
         
            +
                      end
         
     | 
| 
      
 80 
     | 
    
         
            +
                      ips.compact
         
     | 
| 
      
 81 
     | 
    
         
            +
                    end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                    def run_ip_addr
         
     | 
| 
      
 84 
     | 
    
         
            +
                      response = @connection.node_execute('/sbin/ip -4 addr show')
         
     | 
| 
      
 85 
     | 
    
         
            +
                      ips = []
         
     | 
| 
      
 86 
     | 
    
         
            +
                      response.split(/^[0-9]+: /).each do |device|
         
     | 
| 
      
 87 
     | 
    
         
            +
                        next if device.include?('LOOPBACK') || device.include?('NO-CARRIER')
         
     | 
| 
      
 88 
     | 
    
         
            +
                        next if device == ''
         
     | 
| 
      
 89 
     | 
    
         
            +
                        found_ips = IP4REGEX.match(device)
         
     | 
| 
      
 90 
     | 
    
         
            +
                        ips << IP4REGEX.match(device)[1] unless found_ips.nil?
         
     | 
| 
      
 91 
     | 
    
         
            +
                      end
         
     | 
| 
      
 92 
     | 
    
         
            +
                      ips.compact
         
     | 
| 
      
 93 
     | 
    
         
            +
                    end
         
     | 
| 
      
 94 
     | 
    
         
            +
                  end
         
     | 
| 
      
 95 
     | 
    
         
            +
                end
         
     | 
| 
      
 96 
     | 
    
         
            +
              end
         
     | 
| 
      
 97 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Kitchen
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Transport
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Winrm < Kitchen::Transport::Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  # Monkey patch of test-kitchen winrm transport
         
     | 
| 
      
 5 
     | 
    
         
            +
                  # that returns stdout
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class Connection < Kitchen::Transport::Base::Connection
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def node_execute(command, &block)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      session.run_powershell_script(command, &block)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    end
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              module Provisioner
         
     | 
| 
      
 15 
     | 
    
         
            +
                module IpFinder
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # WinRM implementation for returning active non-localhost IPs
         
     | 
| 
      
 17 
     | 
    
         
            +
                  class Winrm
         
     | 
| 
      
 18 
     | 
    
         
            +
                    def initialize(connection)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      @connection = connection
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    def find_ips
         
     | 
| 
      
 23 
     | 
    
         
            +
                      out = @connection.node_execute(
         
     | 
| 
      
 24 
     | 
    
         
            +
                        'Get-NetIPConfiguration | % { $_.ipv4address.IPAddress }')
         
     | 
| 
      
 25 
     | 
    
         
            +
                      data = []
         
     | 
| 
      
 26 
     | 
    
         
            +
                      out[:data].each do |out_data|
         
     | 
| 
      
 27 
     | 
    
         
            +
                        stdout = out_data[:stdout]
         
     | 
| 
      
 28 
     | 
    
         
            +
                        data << stdout.chomp unless stdout.nil?
         
     | 
| 
      
 29 
     | 
    
         
            +
                      end
         
     | 
| 
      
 30 
     | 
    
         
            +
                      data
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,110 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- encoding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Author:: Matt Wrock (<matt@mattwrock.com>)
         
     | 
| 
      
 4 
     | 
    
         
            +
            #
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Copyright (C) 2015, Matt Wrock
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # Licensed under the Apache License, Version 2.0 (the 'License');
         
     | 
| 
      
 8 
     | 
    
         
            +
            # you may not use this file except in compliance with the License.
         
     | 
| 
      
 9 
     | 
    
         
            +
            # You may obtain a copy of the License at
         
     | 
| 
      
 10 
     | 
    
         
            +
            #
         
     | 
| 
      
 11 
     | 
    
         
            +
            #    http://www.apache.org/licenses/LICENSE-2.0
         
     | 
| 
      
 12 
     | 
    
         
            +
            #
         
     | 
| 
      
 13 
     | 
    
         
            +
            # Unless required by applicable law or agreed to in writing, software
         
     | 
| 
      
 14 
     | 
    
         
            +
            # distributed under the License is distributed on an 'AS IS' BASIS,
         
     | 
| 
      
 15 
     | 
    
         
            +
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         
     | 
| 
      
 16 
     | 
    
         
            +
            # See the License for the specific language governing permissions and
         
     | 
| 
      
 17 
     | 
    
         
            +
            # limitations under the License.
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            require 'kitchen'
         
     | 
| 
      
 20 
     | 
    
         
            +
            require 'kitchen/provisioner/chef_zero'
         
     | 
| 
      
 21 
     | 
    
         
            +
            require 'kitchen/provisioner/ip_finder'
         
     | 
| 
      
 22 
     | 
    
         
            +
            require 'net/ping'
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            module Kitchen
         
     | 
| 
      
 25 
     | 
    
         
            +
              module Provisioner
         
     | 
| 
      
 26 
     | 
    
         
            +
                # Nodes provisioner for Kitchen.
         
     | 
| 
      
 27 
     | 
    
         
            +
                #
         
     | 
| 
      
 28 
     | 
    
         
            +
                # @author Matt Wrock <matt@mattwrock.com>
         
     | 
| 
      
 29 
     | 
    
         
            +
                class Nodes < ChefZero
         
     | 
| 
      
 30 
     | 
    
         
            +
                  def create_sandbox
         
     | 
| 
      
 31 
     | 
    
         
            +
                    FileUtils.rm(node_file) if File.exist?(node_file)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    create_node
         
     | 
| 
      
 33 
     | 
    
         
            +
                    super
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  def create_node
         
     | 
| 
      
 37 
     | 
    
         
            +
                    FileUtils.mkdir_p(node_dir) unless Dir.exist?(node_dir)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    template_to_write = node_template
         
     | 
| 
      
 39 
     | 
    
         
            +
                    File.open(node_file, 'w') do |out|
         
     | 
| 
      
 40 
     | 
    
         
            +
                      out << JSON.pretty_generate(template_to_write)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  def ipaddress
         
     | 
| 
      
 45 
     | 
    
         
            +
                    state = Kitchen::StateFile.new(
         
     | 
| 
      
 46 
     | 
    
         
            +
                      config[:kitchen_root],
         
     | 
| 
      
 47 
     | 
    
         
            +
                      instance.name
         
     | 
| 
      
 48 
     | 
    
         
            +
                    ).read
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    if %w(127.0.0.1 localhost).include?(state[:hostname])
         
     | 
| 
      
 51 
     | 
    
         
            +
                      return get_reachable_guest_address(state)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    end
         
     | 
| 
      
 53 
     | 
    
         
            +
                    state[:hostname]
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  def chef_environment
         
     | 
| 
      
 57 
     | 
    
         
            +
                    env = '_default'
         
     | 
| 
      
 58 
     | 
    
         
            +
                    if config[:client_rb] && config[:client_rb][:environment]
         
     | 
| 
      
 59 
     | 
    
         
            +
                      env = config[:client_rb][:environment]
         
     | 
| 
      
 60 
     | 
    
         
            +
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
                    env
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  def node_template
         
     | 
| 
      
 65 
     | 
    
         
            +
                    state = Kitchen::StateFile.new(
         
     | 
| 
      
 66 
     | 
    
         
            +
                      config[:kitchen_root],
         
     | 
| 
      
 67 
     | 
    
         
            +
                      instance.name
         
     | 
| 
      
 68 
     | 
    
         
            +
                    ).read
         
     | 
| 
      
 69 
     | 
    
         
            +
                    state[:username] = instance.driver[:username]
         
     | 
| 
      
 70 
     | 
    
         
            +
                    state[:password] = instance.driver[:password]
         
     | 
| 
      
 71 
     | 
    
         
            +
                    {
         
     | 
| 
      
 72 
     | 
    
         
            +
                      id: instance.name,
         
     | 
| 
      
 73 
     | 
    
         
            +
                      chef_environment: chef_environment,
         
     | 
| 
      
 74 
     | 
    
         
            +
                      automatic: {
         
     | 
| 
      
 75 
     | 
    
         
            +
                        ipaddress: ipaddress,
         
     | 
| 
      
 76 
     | 
    
         
            +
                        platform: instance.platform.name.split('-')[0].downcase,
         
     | 
| 
      
 77 
     | 
    
         
            +
                        fqdn: instance.transport.connection(state).node_execute('hostname -f')[/(\w|\.)+/]
         
     | 
| 
      
 78 
     | 
    
         
            +
                      },
         
     | 
| 
      
 79 
     | 
    
         
            +
                      normal: config[:attributes],
         
     | 
| 
      
 80 
     | 
    
         
            +
                      run_list: config[:run_list]
         
     | 
| 
      
 81 
     | 
    
         
            +
                    }
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  def node_dir
         
     | 
| 
      
 85 
     | 
    
         
            +
                    File.join(config[:test_base_path], 'nodes')
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  def node_file
         
     | 
| 
      
 89 
     | 
    
         
            +
                    File.join(node_dir, "#{instance.name}.json")
         
     | 
| 
      
 90 
     | 
    
         
            +
                  end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                  def get_reachable_guest_address(state)
         
     | 
| 
      
 93 
     | 
    
         
            +
                    active_ips(instance.transport, state).each do |address|
         
     | 
| 
      
 94 
     | 
    
         
            +
                      next if address == '127.0.0.1'
         
     | 
| 
      
 95 
     | 
    
         
            +
                      return address if Net::Ping::External.new.ping(address)
         
     | 
| 
      
 96 
     | 
    
         
            +
                    end
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  def active_ips(transport, state)
         
     | 
| 
      
 100 
     | 
    
         
            +
                    # inject creds into state for legacy drivers
         
     | 
| 
      
 101 
     | 
    
         
            +
                    [:username, :password].each do |prop|
         
     | 
| 
      
 102 
     | 
    
         
            +
                      state[prop] = instance.driver[prop] if instance.driver[prop]
         
     | 
| 
      
 103 
     | 
    
         
            +
                    end
         
     | 
| 
      
 104 
     | 
    
         
            +
                    ips = IpFinder.for_transport(transport, state).find_ips
         
     | 
| 
      
 105 
     | 
    
         
            +
                    fail 'Unable to retrieve IPs' if ips.empty?
         
     | 
| 
      
 106 
     | 
    
         
            +
                    ips
         
     | 
| 
      
 107 
     | 
    
         
            +
                  end
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
              end
         
     | 
| 
      
 110 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- encoding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Author:: Matt Wrock (<matt@mattwrock.com>)
         
     | 
| 
      
 4 
     | 
    
         
            +
            #
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Copyright (C) 2015, Matt Wrock
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
      
 8 
     | 
    
         
            +
            # you may not use this file except in compliance with the License.
         
     | 
| 
      
 9 
     | 
    
         
            +
            # You may obtain a copy of the License at
         
     | 
| 
      
 10 
     | 
    
         
            +
            #
         
     | 
| 
      
 11 
     | 
    
         
            +
            #    http://www.apache.org/licenses/LICENSE-2.0
         
     | 
| 
      
 12 
     | 
    
         
            +
            #
         
     | 
| 
      
 13 
     | 
    
         
            +
            # Unless required by applicable law or agreed to in writing, software
         
     | 
| 
      
 14 
     | 
    
         
            +
            # distributed under the License is distributed on an "AS IS" BASIS,
         
     | 
| 
      
 15 
     | 
    
         
            +
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         
     | 
| 
      
 16 
     | 
    
         
            +
            # See the License for the specific language governing permissions and
         
     | 
| 
      
 17 
     | 
    
         
            +
            # limitations under the License.
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            module Kitchen
         
     | 
| 
      
 20 
     | 
    
         
            +
              # Version string for Nodes Kitchen driver
         
     | 
| 
      
 21 
     | 
    
         
            +
              module Provisioner
         
     | 
| 
      
 22 
     | 
    
         
            +
                NODES_VERSION = '0.4.1'
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,210 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'erb'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'fakefs/safe'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'kitchen'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'kitchen/driver/dummy'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'kitchen/provisioner/nodes'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'kitchen/transport/dummy'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'kitchen/transport/winrm'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'kitchen/transport/ssh'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            describe Kitchen::Provisioner::Nodes do
         
     | 
| 
      
 11 
     | 
    
         
            +
              let(:config) do
         
     | 
| 
      
 12 
     | 
    
         
            +
                {
         
     | 
| 
      
 13 
     | 
    
         
            +
                  test_base_path: '/b',
         
     | 
| 
      
 14 
     | 
    
         
            +
                  kitchen_root: '/r',
         
     | 
| 
      
 15 
     | 
    
         
            +
                  run_list: 'cookbook:recipe',
         
     | 
| 
      
 16 
     | 
    
         
            +
                  attributes: { att_key: 'att_val' },
         
     | 
| 
      
 17 
     | 
    
         
            +
                  client_rb: { environment: 'my_env' }
         
     | 
| 
      
 18 
     | 
    
         
            +
                }
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
              let(:instance) do
         
     | 
| 
      
 21 
     | 
    
         
            +
                double(
         
     | 
| 
      
 22 
     | 
    
         
            +
                  'instance',
         
     | 
| 
      
 23 
     | 
    
         
            +
                  name: 'test_suite',
         
     | 
| 
      
 24 
     | 
    
         
            +
                  suite: suite,
         
     | 
| 
      
 25 
     | 
    
         
            +
                  platform: platform,
         
     | 
| 
      
 26 
     | 
    
         
            +
                  transport: transport,
         
     | 
| 
      
 27 
     | 
    
         
            +
                  driver: Kitchen::Driver::Dummy.new
         
     | 
| 
      
 28 
     | 
    
         
            +
                )
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
              let(:transport) { Kitchen::Transport::Dummy.new }
         
     | 
| 
      
 31 
     | 
    
         
            +
              let(:platform) { double('platform', os_type: nil, name: 'ubuntu') }
         
     | 
| 
      
 32 
     | 
    
         
            +
              let(:suite) { double('suite', name: 'suite') }
         
     | 
| 
      
 33 
     | 
    
         
            +
              let(:state) { { hostname: '192.168.1.10' } }
         
     | 
| 
      
 34 
     | 
    
         
            +
              let(:node) { JSON.parse(File.read(subject.node_file), symbolize_names: true) }
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              before do
         
     | 
| 
      
 37 
     | 
    
         
            +
                FakeFS.activate!
         
     | 
| 
      
 38 
     | 
    
         
            +
                FileUtils.mkdir_p(config[:test_base_path])
         
     | 
| 
      
 39 
     | 
    
         
            +
                allow_any_instance_of(Kitchen::StateFile)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  .to receive(:read).and_return(state)
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
              after do
         
     | 
| 
      
 43 
     | 
    
         
            +
                FakeFS.deactivate!
         
     | 
| 
      
 44 
     | 
    
         
            +
                FakeFS::FileSystem.clear
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              subject { Kitchen::Provisioner::Nodes.new(config).finalize_config!(instance) }
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              it 'creates node' do
         
     | 
| 
      
 50 
     | 
    
         
            +
                subject.create_node
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                expect(File).to exist(subject.node_file)
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              it 'sets the id' do
         
     | 
| 
      
 56 
     | 
    
         
            +
                subject.create_node
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                expect(node[:id]).to eq instance.name
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              it 'sets the environment' do
         
     | 
| 
      
 62 
     | 
    
         
            +
                subject.create_node
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                expect(node[:chef_environment]).to eq config[:client_rb][:environment]
         
     | 
| 
      
 65 
     | 
    
         
            +
              end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              it 'sets the runlist' do
         
     | 
| 
      
 68 
     | 
    
         
            +
                subject.create_node
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                expect(node[:run_list]).to eq config[:run_list]
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              it 'sets the normal attributes' do
         
     | 
| 
      
 74 
     | 
    
         
            +
                subject.create_node
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                expect(node[:normal]).to eq config[:attributes]
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              it 'sets the ip address' do
         
     | 
| 
      
 80 
     | 
    
         
            +
                subject.create_node
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                expect(node[:automatic][:ipaddress]).to eq state[:hostname]
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
              context 'no environment explicitly set' do
         
     | 
| 
      
 86 
     | 
    
         
            +
                before { config.delete(:client_rb) }
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                it 'sets the environment' do
         
     | 
| 
      
 89 
     | 
    
         
            +
                  subject.create_node
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  expect(node[:chef_environment]).to eq '_default'
         
     | 
| 
      
 92 
     | 
    
         
            +
                end
         
     | 
| 
      
 93 
     | 
    
         
            +
              end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
              context 'instance is localhost' do
         
     | 
| 
      
 96 
     | 
    
         
            +
                let(:state) { { hostname: '127.0.0.1' } }
         
     | 
| 
      
 97 
     | 
    
         
            +
                let(:machine_ips) { ['192.168.1.1', '192.168.1.2', '192.168.1.3'] }
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                before do
         
     | 
| 
      
 100 
     | 
    
         
            +
                  allow_any_instance_of(Net::Ping::External).to receive(:ping)
         
     | 
| 
      
 101 
     | 
    
         
            +
                    .and_return(true)
         
     | 
| 
      
 102 
     | 
    
         
            +
                  allow(transport).to receive(:connection)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    .and_return(Kitchen::Transport::Base::Connection.new)
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                context 'cannot find an ip' do
         
     | 
| 
      
 107 
     | 
    
         
            +
                  let(:ifconfig_response) do
         
     | 
| 
      
 108 
     | 
    
         
            +
                    FakeFS.deactivate!
         
     | 
| 
      
 109 
     | 
    
         
            +
                    template = File.read('spec/unit/stubs/ifconfig.txt')
         
     | 
| 
      
 110 
     | 
    
         
            +
                    FakeFS.activate!
         
     | 
| 
      
 111 
     | 
    
         
            +
                    template.gsub!('', machine_ips[0])
         
     | 
| 
      
 112 
     | 
    
         
            +
                    template.gsub!('', machine_ips[1])
         
     | 
| 
      
 113 
     | 
    
         
            +
                    template.gsub!('', machine_ips[2])
         
     | 
| 
      
 114 
     | 
    
         
            +
                  end
         
     | 
| 
      
 115 
     | 
    
         
            +
                  let(:transport) { Kitchen::Transport::Ssh.new }
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                  before do
         
     | 
| 
      
 118 
     | 
    
         
            +
                    allow_any_instance_of(Kitchen::Transport::Base::Connection)
         
     | 
| 
      
 119 
     | 
    
         
            +
                      .to receive(:node_execute).and_return(ifconfig_response)
         
     | 
| 
      
 120 
     | 
    
         
            +
                  end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                  it 'fails' do
         
     | 
| 
      
 123 
     | 
    
         
            +
                    expect { subject.create_node }.to raise_error('Unable to retrieve IPs')
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
                end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                context 'platform is windows' do
         
     | 
| 
      
 128 
     | 
    
         
            +
                  let(:transport) { Kitchen::Transport::Winrm.new }
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                  before do
         
     | 
| 
      
 131 
     | 
    
         
            +
                    data = machine_ips.map { |ip| { stdout: "#{ip}\r\n" } }
         
     | 
| 
      
 132 
     | 
    
         
            +
                    allow_any_instance_of(Kitchen::Transport::Base::Connection).to(
         
     | 
| 
      
 133 
     | 
    
         
            +
                      receive(:node_execute).and_return(data: data)
         
     | 
| 
      
 134 
     | 
    
         
            +
                    )
         
     | 
| 
      
 135 
     | 
    
         
            +
                    allow(platform).to receive(:name).and_return('windows')
         
     | 
| 
      
 136 
     | 
    
         
            +
                  end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                  it 'sets the ip address to the first reachable IP' do
         
     | 
| 
      
 139 
     | 
    
         
            +
                    subject.create_node
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                    expect(node[:automatic][:ipaddress]).to eq machine_ips.first
         
     | 
| 
      
 142 
     | 
    
         
            +
                  end
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                  context 'only the last ip is reachable' do
         
     | 
| 
      
 145 
     | 
    
         
            +
                    before do
         
     | 
| 
      
 146 
     | 
    
         
            +
                      allow_any_instance_of(Net::Ping::External).to receive(:ping)
         
     | 
| 
      
 147 
     | 
    
         
            +
                        .and_return(false)
         
     | 
| 
      
 148 
     | 
    
         
            +
                      allow_any_instance_of(Net::Ping::External).to receive(:ping)
         
     | 
| 
      
 149 
     | 
    
         
            +
                        .with(machine_ips.last).and_return(true)
         
     | 
| 
      
 150 
     | 
    
         
            +
                    end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                    it 'sets the ip address to the last IP' do
         
     | 
| 
      
 153 
     | 
    
         
            +
                      subject.create_node
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                      expect(node[:automatic][:ipaddress]).to eq machine_ips.last
         
     | 
| 
      
 156 
     | 
    
         
            +
                    end
         
     | 
| 
      
 157 
     | 
    
         
            +
                  end
         
     | 
| 
      
 158 
     | 
    
         
            +
                end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                context 'platform is *nix' do
         
     | 
| 
      
 161 
     | 
    
         
            +
                  let(:ifconfig_response) do
         
     | 
| 
      
 162 
     | 
    
         
            +
                    FakeFS.deactivate!
         
     | 
| 
      
 163 
     | 
    
         
            +
                    template = File.read('spec/unit/stubs/ifconfig.txt')
         
     | 
| 
      
 164 
     | 
    
         
            +
                    FakeFS.activate!
         
     | 
| 
      
 165 
     | 
    
         
            +
                    template.gsub!('1.1.1.1', machine_ips[0])
         
     | 
| 
      
 166 
     | 
    
         
            +
                    template.gsub!('2.2.2.2', machine_ips[1])
         
     | 
| 
      
 167 
     | 
    
         
            +
                    template.gsub!('3.3.3.3', machine_ips[2])
         
     | 
| 
      
 168 
     | 
    
         
            +
                  end
         
     | 
| 
      
 169 
     | 
    
         
            +
                  let(:transport) { Kitchen::Transport::Ssh.new }
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
                  before do
         
     | 
| 
      
 172 
     | 
    
         
            +
                    allow_any_instance_of(Kitchen::Transport::Base::Connection)
         
     | 
| 
      
 173 
     | 
    
         
            +
                      .to receive(:node_execute).and_return(ifconfig_response)
         
     | 
| 
      
 174 
     | 
    
         
            +
                  end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                  it 'sets the ip address to the RUNNING IP that is not localhost' do
         
     | 
| 
      
 177 
     | 
    
         
            +
                    subject.create_node
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                    expect(node[:automatic][:ipaddress]).to eq machine_ips[1]
         
     | 
| 
      
 180 
     | 
    
         
            +
                  end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                  context 'ifconfig not supported' do
         
     | 
| 
      
 183 
     | 
    
         
            +
                    let(:ip_response) do
         
     | 
| 
      
 184 
     | 
    
         
            +
                      FakeFS.deactivate!
         
     | 
| 
      
 185 
     | 
    
         
            +
                      template = File.read('spec/unit/stubs/ip.txt')
         
     | 
| 
      
 186 
     | 
    
         
            +
                      FakeFS.activate!
         
     | 
| 
      
 187 
     | 
    
         
            +
                      template.gsub!('1.1.1.1', machine_ips[0])
         
     | 
| 
      
 188 
     | 
    
         
            +
                      template.gsub!('2.2.2.2', machine_ips[1])
         
     | 
| 
      
 189 
     | 
    
         
            +
                      template.gsub!('3.3.3.3', machine_ips[2])
         
     | 
| 
      
 190 
     | 
    
         
            +
                    end
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                    before do
         
     | 
| 
      
 193 
     | 
    
         
            +
                      allow_any_instance_of(Kitchen::Transport::Base::Connection)
         
     | 
| 
      
 194 
     | 
    
         
            +
                        .to receive(:node_execute).with('/sbin/ifconfig -a')
         
     | 
| 
      
 195 
     | 
    
         
            +
                        .and_raise(Kitchen::Transport::TransportFailed.new(''))
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
                      allow_any_instance_of(Kitchen::Transport::Base::Connection)
         
     | 
| 
      
 198 
     | 
    
         
            +
                        .to receive(:node_execute).with('/sbin/ip -4 addr show')
         
     | 
| 
      
 199 
     | 
    
         
            +
                        .and_return(ip_response)
         
     | 
| 
      
 200 
     | 
    
         
            +
                    end
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
                    it 'sets the ip address to the connected IP that is not localhost' do
         
     | 
| 
      
 203 
     | 
    
         
            +
                      subject.create_node
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                      expect(node[:automatic][:ipaddress]).to eq machine_ips[0]
         
     | 
| 
      
 206 
     | 
    
         
            +
                    end
         
     | 
| 
      
 207 
     | 
    
         
            +
                  end
         
     | 
| 
      
 208 
     | 
    
         
            +
                end
         
     | 
| 
      
 209 
     | 
    
         
            +
              end
         
     | 
| 
      
 210 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            bash: warning: setlocale: LC_ALL: cannot change locale (en_US)
         
     | 
| 
      
 2 
     | 
    
         
            +
            docker0   Link encap:Ethernet  HWaddr 56:84:7a:fe:97:99
         
     | 
| 
      
 3 
     | 
    
         
            +
                      inet addr:1.1.1.1  Bcast:0.0.0.0  Mask:255.255.0.0
         
     | 
| 
      
 4 
     | 
    
         
            +
                      UP BROADCAST MULTICAST  MTU:1500  Metric:1
         
     | 
| 
      
 5 
     | 
    
         
            +
                      RX packets:0 errors:0 dropped:0 overruns:0 frame:0
         
     | 
| 
      
 6 
     | 
    
         
            +
                      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
         
     | 
| 
      
 7 
     | 
    
         
            +
                      collisions:0 txqueuelen:0
         
     | 
| 
      
 8 
     | 
    
         
            +
                      RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            eth0      Link encap:Ethernet  HWaddr 08:00:27:88:0c:a6
         
     | 
| 
      
 11 
     | 
    
         
            +
                      inet addr:2.2.2.2  Bcast:10.0.2.255  Mask:255.255.255.0
         
     | 
| 
      
 12 
     | 
    
         
            +
                      inet6 addr: fe80::a00:27ff:fe88:ca6/64 Scope:Link
         
     | 
| 
      
 13 
     | 
    
         
            +
                      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
         
     | 
| 
      
 14 
     | 
    
         
            +
                      RX packets:10262 errors:0 dropped:0 overruns:0 frame:0
         
     | 
| 
      
 15 
     | 
    
         
            +
                      TX packets:7470 errors:0 dropped:0 overruns:0 carrier:0
         
     | 
| 
      
 16 
     | 
    
         
            +
                      collisions:0 txqueuelen:1000
         
     | 
| 
      
 17 
     | 
    
         
            +
                      RX bytes:1497781 (1.4 MB)  TX bytes:1701791 (1.7 MB)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            lo        Link encap:Local Loopback
         
     | 
| 
      
 20 
     | 
    
         
            +
                      inet addr:127.0.0.1  Mask:255.0.0.0
         
     | 
| 
      
 21 
     | 
    
         
            +
                      inet6 addr: ::1/128 Scope:Host
         
     | 
| 
      
 22 
     | 
    
         
            +
                      UP LOOPBACK RUNNING  MTU:65536  Metric:1
         
     | 
| 
      
 23 
     | 
    
         
            +
                      RX packets:0 errors:0 dropped:0 overruns:0 frame:0
         
     | 
| 
      
 24 
     | 
    
         
            +
                      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
         
     | 
| 
      
 25 
     | 
    
         
            +
                      collisions:0 txqueuelen:0
         
     | 
| 
      
 26 
     | 
    
         
            +
                      RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            # The following represents the format of ifconfig from CentOS 7.1
         
     | 
| 
      
 29 
     | 
    
         
            +
            enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
         
     | 
| 
      
 30 
     | 
    
         
            +
                    inet 3.3.3.3  netmask 255.255.255.0  broadcast 3.3.3.0
         
     | 
| 
      
 31 
     | 
    
         
            +
                    inet6 fe80::a00:27ff:fe5e:e9b0  prefixlen 64  scopeid 0x20<link>
         
     | 
| 
      
 32 
     | 
    
         
            +
                    ether 08:00:27:5e:e9:b0  txqueuelen 1000  (Ethernet)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    RX packets 7961  bytes 823710 (804.4 KiB)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    RX errors 0  dropped 0  overruns 0  frame 0
         
     | 
| 
      
 35 
     | 
    
         
            +
                    TX packets 263  bytes 50868 (49.6 KiB)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            bash: warning: setlocale: LC_ALL: cannot change locale (en_US)
         
     | 
| 
      
 2 
     | 
    
         
            +
            1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
         
     | 
| 
      
 3 
     | 
    
         
            +
                inet 127.0.0.1/8 scope host lo
         
     | 
| 
      
 4 
     | 
    
         
            +
                   valid_lft forever preferred_lft forever
         
     | 
| 
      
 5 
     | 
    
         
            +
            3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
         
     | 
| 
      
 6 
     | 
    
         
            +
                inet 1.1.1.1/24 brd 192.168.1.255 scope global wlan0
         
     | 
| 
      
 7 
     | 
    
         
            +
                   valid_lft forever preferred_lft forever
         
     | 
| 
      
 8 
     | 
    
         
            +
            5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
         
     | 
| 
      
 9 
     | 
    
         
            +
                inet 2.2.2.2/16 scope global docker0
         
     | 
| 
      
 10 
     | 
    
         
            +
                   valid_lft forever preferred_lft forever
         
     | 
| 
      
 11 
     | 
    
         
            +
            # The following represents the format of ipaddr from CentOS 7.1 (which is the same in this case, but
         
     | 
| 
      
 12 
     | 
    
         
            +
            # adding for completeness)
         
     | 
| 
      
 13 
     | 
    
         
            +
            6: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
         
     | 
| 
      
 14 
     | 
    
         
            +
                inet 3.3.3.3/24 brd 3.3.3.255 scope global dynamic enp0s8
         
     | 
| 
      
 15 
     | 
    
         
            +
                   valid_lft 966sec preferred_lft 966sec
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,178 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: kitchen-nodes-fqdn
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.4.1
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Matt Wrock
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Marcin Cabaj
         
     | 
| 
      
 9 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 10 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 11 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2015-09-30 00:00:00.000000000 Z
         
     | 
| 
      
 13 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 14 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 15 
     | 
    
         
            +
              name: net-ping
         
     | 
| 
      
 16 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 17 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 18 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 19 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 20 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 21 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 22 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 23 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 24 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 25 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 26 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 27 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 28 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 29 
     | 
    
         
            +
              name: win32-security
         
     | 
| 
      
 30 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 31 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 32 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 33 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 34 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 35 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 36 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 37 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 38 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 39 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 40 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 41 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 42 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 43 
     | 
    
         
            +
              name: test-kitchen
         
     | 
| 
      
 44 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 45 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 46 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 47 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 48 
     | 
    
         
            +
                    version: '1.4'
         
     | 
| 
      
 49 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 50 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 51 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 52 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 53 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 54 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 55 
     | 
    
         
            +
                    version: '1.4'
         
     | 
| 
      
 56 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 57 
     | 
    
         
            +
              name: bundler
         
     | 
| 
      
 58 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 59 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 60 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 61 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 62 
     | 
    
         
            +
                    version: '1.3'
         
     | 
| 
      
 63 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 64 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 65 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 66 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 67 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 68 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 69 
     | 
    
         
            +
                    version: '1.3'
         
     | 
| 
      
 70 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 71 
     | 
    
         
            +
              name: fakefs
         
     | 
| 
      
 72 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 73 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 74 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 75 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 76 
     | 
    
         
            +
                    version: '0.4'
         
     | 
| 
      
 77 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 78 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 79 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 80 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 81 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 82 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 83 
     | 
    
         
            +
                    version: '0.4'
         
     | 
| 
      
 84 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 85 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 86 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 87 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 88 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 89 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 90 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 91 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 92 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 93 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 94 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 95 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 96 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 97 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 98 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 99 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 100 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 101 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 102 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 103 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 104 
     | 
    
         
            +
                    version: '3.2'
         
     | 
| 
      
 105 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 106 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 107 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 108 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 109 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 110 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 111 
     | 
    
         
            +
                    version: '3.2'
         
     | 
| 
      
 112 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 113 
     | 
    
         
            +
              name: rubocop
         
     | 
| 
      
 114 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 115 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 116 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 117 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 118 
     | 
    
         
            +
                    version: '0.29'
         
     | 
| 
      
 119 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 120 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 121 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 122 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 123 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 124 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 125 
     | 
    
         
            +
                    version: '0.29'
         
     | 
| 
      
 126 
     | 
    
         
            +
            description: A Test Kitchen Provisioner for Chef Nodes
         
     | 
| 
      
 127 
     | 
    
         
            +
            email:
         
     | 
| 
      
 128 
     | 
    
         
            +
            - matt@mattwrock.com
         
     | 
| 
      
 129 
     | 
    
         
            +
            - mcabaj@gmail.com
         
     | 
| 
      
 130 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 131 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 132 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 133 
     | 
    
         
            +
            files:
         
     | 
| 
      
 134 
     | 
    
         
            +
            - ".gitignore"
         
     | 
| 
      
 135 
     | 
    
         
            +
            - ".rubocop.yml"
         
     | 
| 
      
 136 
     | 
    
         
            +
            - ".travis.yml"
         
     | 
| 
      
 137 
     | 
    
         
            +
            - CHANGELOG.md
         
     | 
| 
      
 138 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 139 
     | 
    
         
            +
            - LICENSE
         
     | 
| 
      
 140 
     | 
    
         
            +
            - README.md
         
     | 
| 
      
 141 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 142 
     | 
    
         
            +
            - kitchen-nodes.gemspec
         
     | 
| 
      
 143 
     | 
    
         
            +
            - lib/kitchen/provisioner/ip_finder.rb
         
     | 
| 
      
 144 
     | 
    
         
            +
            - lib/kitchen/provisioner/ip_finder/ssh.rb
         
     | 
| 
      
 145 
     | 
    
         
            +
            - lib/kitchen/provisioner/ip_finder/winrm.rb
         
     | 
| 
      
 146 
     | 
    
         
            +
            - lib/kitchen/provisioner/nodes.rb
         
     | 
| 
      
 147 
     | 
    
         
            +
            - lib/kitchen/provisioner/nodes_version.rb
         
     | 
| 
      
 148 
     | 
    
         
            +
            - spec/unit/nodes_spec.rb
         
     | 
| 
      
 149 
     | 
    
         
            +
            - spec/unit/stubs/ifconfig.txt
         
     | 
| 
      
 150 
     | 
    
         
            +
            - spec/unit/stubs/ip.txt
         
     | 
| 
      
 151 
     | 
    
         
            +
            homepage: ''
         
     | 
| 
      
 152 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 153 
     | 
    
         
            +
            - Apache 2.0
         
     | 
| 
      
 154 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 155 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 156 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 157 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 158 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 159 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 160 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 161 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 162 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 163 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 164 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 165 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 166 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 167 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 168 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 169 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 170 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 171 
     | 
    
         
            +
            rubygems_version: 2.4.5.1
         
     | 
| 
      
 172 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 173 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 174 
     | 
    
         
            +
            summary: A Test Kitchen Provisioner for Chef Nodes
         
     | 
| 
      
 175 
     | 
    
         
            +
            test_files:
         
     | 
| 
      
 176 
     | 
    
         
            +
            - spec/unit/nodes_spec.rb
         
     | 
| 
      
 177 
     | 
    
         
            +
            - spec/unit/stubs/ifconfig.txt
         
     | 
| 
      
 178 
     | 
    
         
            +
            - spec/unit/stubs/ip.txt
         
     |