diff --git a/lib/chef/knife/cloud/openstack_service.rb b/lib/chef/knife/cloud/openstack_service.rb index 0df6b1dc..59c16caf 100644 --- a/lib/chef/knife/cloud/openstack_service.rb +++ b/lib/chef/knife/cloud/openstack_service.rb @@ -36,6 +36,26 @@ def initialize(options = {}) def add_api_endpoint @auth_params.merge!({:openstack_auth_url => Chef::Config[:knife][:api_endpoint]}) unless Chef::Config[:knife][:api_endpoint].nil? end + + def get_server(search_term) + begin + if server = connection.servers.get(search_term) + return server + end + + if servers = connection.servers.all(:name => search_term) + if servers.length > 1 + error_message = "Multiple server matches found for '#{search_term}', use an instance_id to be more specific." + ui.fatal(error_message) + raise CloudExceptions::ValidationError, error_message + else + servers.first + end + end + rescue Excon::Errors::BadRequest => e + handle_excon_exception(CloudExceptions::KnifeCloudError, e) + end + end end end end diff --git a/spec/unit/openstack_service_spec.rb b/spec/unit/openstack_service_spec.rb index 9a84a63e..dc1ad246 100644 --- a/spec/unit/openstack_service_spec.rb +++ b/spec/unit/openstack_service_spec.rb @@ -48,4 +48,40 @@ Chef::Config[:knife][:openstack_endpoint_type].should == nil end end + + describe "#get_server" do + before(:each) do + @instance = Chef::Knife::Cloud::OpenstackService.new + @instance.stub_chain(:connection,:servers,:get) + end + + context "when instance_id given" do + it "return server" do + server_id = "123f456-123-453e-9c0c-12345a6789" + @instance.connection.servers.should_receive(:get).and_return(server_id) + @instance.connection.servers.should_not_receive(:all) + @instance.get_server(server_id).should == server_id + end + end + + context "when instance_name given" do + before(:each) do + @instance.connection.servers.should_receive(:get).and_return(nil) + end + + let (:server_name) { "testname" } + + it "return server" do + @instance.connection.servers.should_receive(:all).with({:name=>server_name}).and_return([server_name]) + @instance.get_server(server_name).should == server_name + end + + it "raise error if multiple server matches found for given instance name" do + error_message = "Multiple server matches found for '#{server_name}', use an instance_id to be more specific." + @instance.connection.servers.should_receive(:all).with({:name=>server_name}).and_return([server_name,server_name]) + @instance.stub_chain(:ui,:fatal) + expect { @instance.get_server(server_name) }.to raise_error(Chef::Knife::Cloud::CloudExceptions::ValidationError, error_message) + end + end + end end