commit 9271206dc7cd86ea0dccbdfcfc026817f8e610d1 Author: Jay Pipes Date: Wed Nov 7 20:52:47 2012 -0500 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..e9d0128e --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +Cheffile.lock +.bundle +.cache +.rvmrc +*.swp +/cookbooks +/tmp diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..4a583b32 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,12 @@ +# CHANGELOG for cookbook-openstack-utils + +This file is used to list changes made in each version of cookbook-openstack-utils. + +## 0.0.1: + +* Initial release of cookbook-openstack-utils + +- - - +Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. + +The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/Cheffile b/Cheffile new file mode 100644 index 00000000..aea12960 --- /dev/null +++ b/Cheffile @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby + +site "http://community.opscode.com/api/v1" diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..b4d5f873 --- /dev/null +++ b/Gemfile @@ -0,0 +1,6 @@ +source :rubygems + +gem "chefspec", :git => "git://github.com/acrmp/chefspec.git" +gem "librarian", "~> 0.0.24" +gem "foodcritic", "~> 1.6.1" +gem "hashie", "~> 1.2.0" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..92f939c3 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,121 @@ +GIT + remote: git://github.com/acrmp/chefspec.git + revision: 5cb01c464a572132edac802549efbc3c7c85485a + specs: + chefspec (0.8.0) + chef (>= 0.9.12) + erubis + minitest-chef-handler (~> 0.6.0) + rspec (~> 2.11.0) + +GEM + remote: http://rubygems.org/ + specs: + archive-tar-minitar (0.5.2) + builder (3.1.4) + bunny (0.7.9) + chef (10.16.2) + bunny (>= 0.6.0, < 0.8.0) + erubis + highline (>= 1.6.9) + json (>= 1.4.4, <= 1.6.1) + mixlib-authentication (>= 1.3.0) + mixlib-cli (>= 1.1.0) + mixlib-config (>= 1.1.2) + mixlib-log (>= 1.3.0) + mixlib-shellout + moneta + net-ssh (~> 2.2.2) + net-ssh-multi (~> 1.1.0) + ohai (>= 0.6.0) + rest-client (>= 1.0.4, < 1.7.0) + treetop (~> 1.4.9) + uuidtools + yajl-ruby (~> 1.1) + ci_reporter (1.7.3) + builder (>= 2.1.2) + coderay (1.0.8) + diff-lcs (1.1.3) + erubis (2.7.0) + foodcritic (1.6.1) + erubis + gherkin (~> 2.11.1) + gist (~> 3.1.0) + nokogiri (= 1.5.0) + pry (~> 0.9.8.4) + rak (~> 1.4) + treetop (~> 1.4.10) + yajl-ruby (~> 1.1.0) + gherkin (2.11.5) + json (>= 1.4.6) + gist (3.1.0) + hashie (1.2.0) + highline (1.6.15) + ipaddress (0.8.0) + json (1.6.1) + librarian (0.0.25) + archive-tar-minitar (>= 0.5.2) + chef (>= 0.10) + highline + thor (~> 0.15) + method_source (0.7.1) + mime-types (1.19) + minitest (4.2.0) + minitest-chef-handler (0.6.3) + chef + ci_reporter + minitest + mixlib-authentication (1.3.0) + mixlib-log + mixlib-cli (1.2.2) + mixlib-config (1.1.2) + mixlib-log (1.4.1) + mixlib-shellout (1.1.0) + moneta (0.6.0) + net-ssh (2.2.2) + net-ssh-gateway (1.1.0) + net-ssh (>= 1.99.1) + net-ssh-multi (1.1) + net-ssh (>= 2.1.4) + net-ssh-gateway (>= 0.99.0) + nokogiri (1.5.0) + ohai (6.14.0) + ipaddress + mixlib-cli + mixlib-config + mixlib-log + systemu + yajl-ruby + polyglot (0.3.3) + pry (0.9.8.4) + coderay (~> 1.0.5) + method_source (~> 0.7.1) + slop (>= 2.4.4, < 3) + rak (1.4) + rest-client (1.6.7) + mime-types (>= 1.16) + rspec (2.11.0) + rspec-core (~> 2.11.0) + rspec-expectations (~> 2.11.0) + rspec-mocks (~> 2.11.0) + rspec-core (2.11.1) + rspec-expectations (2.11.3) + diff-lcs (~> 1.1.3) + rspec-mocks (2.11.3) + slop (2.4.4) + systemu (2.5.2) + thor (0.16.0) + treetop (1.4.12) + polyglot + polyglot (>= 0.3.1) + uuidtools (2.1.3) + yajl-ruby (1.1.0) + +PLATFORMS + ruby + +DEPENDENCIES + chefspec! + foodcritic (~> 1.6.1) + hashie (~> 1.2.0) + librarian (~> 0.0.24) diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..68c771a0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,176 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + diff --git a/README.md b/README.md new file mode 100644 index 00000000..b504ec0e --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +Description +=========== + +Cookbook containing common setup recipes and attributes that describe +an OpenStack deployment. + +Requirements +============ + +* Chef 0.8+ + +Attributes +========== + +Please see the extensive inline documentation in `attributes/default.rb` for descriptions +of all the settable attributes for this cookbook. + +Note that all attributes are in the `default["openstack"]` "namespace" + +Testing +===== + +This cookbook is using [ChefSpec](https://github.com/acrmp/chefspec) for testing. + + $ cd $repo + $ bundle + $ librarian-chef install + $ ln -s ../ cookbooks/$short_repo_name # doesn't contain "cookbook-" + $ foodcritic cookbooks/$short_repo_name + $ bundle exec rspec cookbooks/$short_repo_name + +License and Author +================== + +Author:: Jay Pipes () + +Copyright 2012, Jay Pipes + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/attributes/default.rb b/attributes/default.rb new file mode 100644 index 00000000..7cf27b10 --- /dev/null +++ b/attributes/default.rb @@ -0,0 +1,141 @@ +# +# Cookbook Name:: openstack-common +# Attributes:: default +# +# Copyright 2012, Jay Pipes +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# ======================== OpenStack Endpoints ================================ +# +# OpenStack recipes often need information about the various service +# endpoints in the deployment. For instance, the cookbook that deploys +# the Nova API service will need to set the glance_api_servers configuration +# option in the nova.conf, and the cookbook setting up the Glance image +# service might need information on the Swift proxy endpoint, etc. Having +# all of this related OpenStack endpoint information in a single set of +# common attributes in the openstack-common cookbook attributes means that +# instead of doing funky role-based lookups, a deployment zone's OpenStack +# endpoint information can simply be accessed by having the +# openstack-common::default recipe added to some base role definition file +# that all OpenStack nodes add to their run list. +# +# node["openstack"]["endpoints"] is a hash of hashes, where each value hash +# contains one of more of the following keys: +# +# - scheme +# - uri +# - host +# - port +# - path +# +# If the uri key is set, its value is used as the full URI for the endpoint. +# If the uri key is not set, the endpoint's full URI is constructed from the +# component parts. This allows setups that use some standardized DNS names for +# OpenStack service endpoints in a deployment zone as well as setups that +# instead assign IP addresses (for an actual node or a load balanced virtual +# IP) in a network to a particular OpenStack service endpoint. + +default["openstack"]["endpoints"] = {} +ep = default["openstack"]["endpoints"] + +# ******************** OpenStack Identity Endpoints *************************** + +# The OpenStack Identity (Keystone) API endpoint. This is commonly called +# the Keystone Service endpoint... +ep["identity-api"]["host"] = "127.0.0.1" +ep["identity-api"]["scheme"] = "https" +ep["identity-api"]["port"] = 35357 +ep["identity-api"]["path"] = "/v2.0" + +# The OpenStack Identity (Keystone) Admin API endpoint +ep["identity-admin"]["host"] = "127.0.0.1" +ep["identity-admin"]["scheme"] = "https" +ep["identity-admin"]["port"] = 5000 +ep["identity-admin"]["path"] = "/v2.0" + +# ****************** OpenStack Compute Endpoints ****************************** + +# The OpenStack Compute (Nova) Native API endpoint +ep["compute-api"]["host"] = "127.0.0.1" +ep["compute-api"]["scheme"] = "https" +ep["compute-api"]["port"] = 8774 +ep["compute-api"]["path"] = "/v2/%(tenant_id)s" + +# The OpenStack Compute (Nova) EC2 API endpoint +ep["compute-ec2-api"]["host"] = "127.0.0.1" +ep["compute-ec2-api"]["scheme"] = "https" +ep["compute-ec2-api"]["port"] = 8773 +ep["compute-ec2-api"]["path"] = "/services/Cloud" + +# The OpenStack Compute (Nova) EC2 Admin API endpoint +ep["compute-ec2-admin"]["host"] = "127.0.0.1" +ep["compute-ec2-admin"]["scheme"] = "https" +ep["compute-ec2-admin"]["port"] = 8773 +ep["compute-ec2-admin"]["path"] = "/services/Admin" + +# The OpenStack Compute (Nova) XVPvnc endpoint +ep["compute-xvpvnc"]["host"] = "127.0.0.1" +ep["compute-xvpvnc"]["scheme"] = "https" +ep["compute-xvpvnc"]["port"] = 6081 +ep["compute-xvpvnc"]["path"] = "/console" + +# The OpenStack Compute (Nova) novnc endpoint +ep["compute-novnc"]["host"] = "127.0.0.1" +ep["compute-novnc"]["scheme"] = "https" +ep["compute-novnc"]["port"] = 6080 +ep["compute-novnc"]["path"] = "/vnc_auto.html" + +# The OpenStack Compute (Nova) novnc server endpoint +# TODO(jaypipes) Is this necessary? It's the same as the novnc endpoint... +ep["compute-novnc-server"]["host"] = "127.0.0.1" +ep["compute-novnc-server"]["scheme"] = "https" +ep["compute-novnc-server"]["port"] = 6080 +ep["compute-novnc-server"]["path"] = "/vnc_auto.html" + +# The OpenStack Compute (Nova) Volume endpoint +# Note that this endpoint is NOT a Cinder endpoint. This is the +# older nova-volume service. +ep["compute-volume"]["host"] = "127.0.0.1" +ep["compute-volume"]["scheme"] = "https" +ep["compute-volume"]["port"] = 8776 +ep["compute-volume"]["path"] = "/v1/%(tenant_id)s" + +# ******************** OpenStack Image Endpoints ****************************** + +# The OpenStack Image (Glance) API endpoint +ep["image-api"]["host"] = "127.0.0.1" +ep["image-api"]["scheme"] = "https" +ep["image-api"]["port"] = 9292 +ep["image-api"]["path"] = "/v2" + +# The OpenStack Image (Glance) Registry API endpoint +ep["image-registry"]["host"] = "127.0.0.1" +ep["image-registry"]["scheme"] = "https" +ep["image-registry"]["port"] = 9191 +ep["image-registry"]["path"] = "/v2" + +# Alternately, if you used some standardized DNS naming scheme, you could +# do something like this, which would override any part-wise specifications above. +# +# ep["identity-api"]["uri"] = "https://identity.example.com:35357/v2.0" +# ep["identity-admin"]["uri"] = "https://identity.example.com:5000/v2.0" +# ep["compute-api"]["uri"] = "https://compute.example.com:8774/v2/%(tenant_id)s" +# ep["compute-ec2-api"]["uri"] = "https://ec2.example.com:8773/services/Cloud" +# ep["compute-ec2-admin"]["uri"] = "https://ec2.example.com:8773/services/Admin" +# ep["compute-xvpvnc"]["uri"] = "https://xvpvnc.example.com:6081/console" +# ep["compute-novnc"]["uri"] = "https://novnc.example.com:6080/vnc_auto.html" +# ep["compute-volume"]["uri"] = "https://volume.example.com:8776/"v1/%(tenant_id)s" +# ep["image-api"]["uri"] = "https://image.example.com:9292/v2" +# ep["image-registry"]["uri"] = "https://image.example.com:9191/v2" diff --git a/libraries/default.rb b/libraries/default.rb new file mode 100644 index 00000000..20b619d9 --- /dev/null +++ b/libraries/default.rb @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby + +# +# Cookbook Name:: openstack-common +# library:: default +# +# Copyright 2012, Jay Pipes +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module Openstack + # Instead of specifying the verbose node["openstack"]["endpoints"][name], + # this shortcut allows the simpler and shorter endpoint(name) + def endpoint(name) + @node["openstack"]["endpoints"][name] + rescue + nil + end + + # Shortcut to get the full URI for an endpoint. If the "uri" key isn't + # set in the endpoint hash, we use the Openstack::get_uri_from_mash + # library routine from the openstack-utils cookbook to grab a URI object + # and construct the URI object from the endpoint parts. + def endpoint_uri(name) + ep = endpoint(name) + if ep and ep.has_key?("uri") + ep["uri"] + elsif ep + ::Openstack::get_uri_from_mash(ep).to_s + end + end + + # Useful for iterating over the OpenStack endpoints + def endpoints(&block) + @node["openstack"]["endpoints"].each do | name, info | + block.call(name, info) + end + end +end diff --git a/metadata.rb b/metadata.rb new file mode 100644 index 00000000..d1c2c0ab --- /dev/null +++ b/metadata.rb @@ -0,0 +1,7 @@ +maintainer "Jay Pipes" +maintainer_email "jaypipes@gmail.com" +license "Apache 2.0" +description "Common OpenStack attributes, libraries and recipes." +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version "0.0.1" +depends "openstack-utils" diff --git a/recipes/default.rb b/recipes/default.rb new file mode 100644 index 00000000..3dc29f8a --- /dev/null +++ b/recipes/default.rb @@ -0,0 +1,18 @@ +# +# Cookbook Name:: openstack-utils +# library:: default +# +# Copyright 2012, Jay Pipes +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/spec/default_spec.rb b/spec/default_spec.rb new file mode 100644 index 00000000..7f90e93a --- /dev/null +++ b/spec/default_spec.rb @@ -0,0 +1,26 @@ +require "chefspec" +require "hashie" +require ::File.join ::File.dirname(__FILE__), "..", "libraries", "default" + +describe ::Openstack do + before do + @chef_run = ::ChefSpec::ChefRunner.new.converge "openstack-common::default" + @subject = ::Object.new.extend(::Openstack) + end + + describe "#endpoint" do + it "returns nil when no openstack.endpoints not in node attrs" do + @subject.instance_variable_set(:@node, {}) + @subject.endpoint("nonexisting").should be_nil + end + it "returns nil when no such endpoint was found" do + @subject.instance_variable_set(:@node, @chef_run.node) + @subject.endpoint("nonexisting").should be_nil + end + it "returns endpoint hash when found" do + @subject.instance_variable_set(:@node, @chef_run.node) + result = @subject.endpoint("compute-api") + result.should be_nil + end + end +end