# # Author:: Mukta Aphale () # Copyright:: Copyright (c) 2013-2014 Chef Software, Inc. require File.expand_path('../../spec_helper', __FILE__) require 'fog' require 'chef/knife/bootstrap' require 'chef/knife/bootstrap_windows_winrm' describe Chef::Knife::OpenstackServerCreate do before do @openstack_connection = double(Fog::Compute::OpenStack) @openstack_connection.stub_chain(:flavors, :find).and_return double('flavor', {:id => 'flavor_id'}) @openstack_connection.stub_chain(:images, :find).and_return double('image', {:id => 'image_id'}) @openstack_connection.stub_chain(:addresses).and_return [double('addresses', { :instance_id => nil, :ip => '111.111.111.111', :fixed_ip => true })] @knife_openstack_create = Chef::Knife::OpenstackServerCreate.new @knife_openstack_create.initial_sleep_delay = 0 @knife_openstack_create.stub(:tcp_test_ssh).and_return(true) @knife_openstack_create.stub(:tcp_test_winrm).and_return(true) { :image => 'image', :openstack_username => 'openstack_username', :openstack_password => 'openstack_password', :openstack_auth_url => 'openstack_auth_url', :server_create_timeout => 1000 }.each do |key, value| Chef::Config[:knife][key] = value end @knife_openstack_create.stub(:msg_pair) @knife_openstack_create.stub(:puts) @knife_openstack_create.stub(:print) @openstack_servers = double() @new_openstack_server = double() @openstack_server_attribs = { :name => 'Mock Server', :id => 'id-123456', :key_name => 'key_name', :flavor => 'flavor_id', :image => 'image_id', :availability_zone => 'zone1', :addresses => { 'foo' => [{'addr' => '34.56.78.90'}], 'public' => [{'addr' => '75.101.253.10'}], 'private' => [{'addr' => '10.251.75.20'}] }, :password => 'password' } @openstack_server_attribs.each_pair do |attrib, value| @new_openstack_server.stub(attrib).and_return(value) end end describe "options" do before do @options = @knife_openstack_create.options end it "ensures default options" do @options[:bootstrap_protocol][:default].should == nil @options[:distro][:default].should == 'chef-full' @options[:availability_zone][:default].should == nil @options[:metadata][:default].should == nil @options[:floating_ip][:default].should == '-1' @options[:host_key_verify][:default].should == true @options[:private_network][:default].should == false @options[:network][:default].should == true @options[:bootstrap_network][:default].should == 'public' @options[:run_list][:default].should == [] @options[:security_groups][:default].should == ['default'] @options[:server_create_timeout][:default].should == 600 @options[:ssh_port][:default].should == '22' @options[:ssh_user][:default].should == 'root' @options[:first_boot_attributes][:default].should == {} end it "doesn't set an OpenStack endpoint type by default" do Chef::Config[:knife][:openstack_endpoint_type].should == nil end it "user_data should be empty" do Chef::Config[:knife][:user_data].should == nil end end describe "run" do before do @openstack_servers.should_receive(:create).and_return(@new_openstack_server) @openstack_connection.should_receive(:servers).and_return(@openstack_servers) Fog::Compute::OpenStack.should_receive(:new).and_return(@openstack_connection) @bootstrap = Chef::Knife::Bootstrap.new Chef::Knife::Bootstrap.stub(:new).and_return(@bootstrap) @bootstrap.should_receive(:run) @knife_openstack_create.config[:run_list] = [] @knife_openstack_create.config[:floating_ip] = '-1' end it "Creates an OpenStack instance and bootstraps it" do @new_openstack_server.should_receive(:wait_for).and_return(true) @knife_openstack_create.run end it "Creates an OpenStack instance for Windows and bootstraps it" do @bootstrap_win = Chef::Knife::BootstrapWindowsWinrm.new Chef::Knife::BootstrapWindowsWinrm.stub(:new).and_return(@bootstrap_win) Chef::Config[:knife][:bootstrap_protocol] = 'winrm' @new_openstack_server.should_receive(:wait_for).and_return(true) @knife_openstack_create.run end it "creates an OpenStack instance, assigns existing floating ip and bootstraps it" do @knife_openstack_create.config[:floating_ip] = "111.111.111.111" @new_openstack_server.should_receive(:wait_for).and_return(true) @new_openstack_server.should_receive(:associate_address).with('111.111.111.111') @knife_openstack_create.run end end describe "when configuring the bootstrap process" do before do @knife_openstack_create.config[:ssh_user] = "ubuntu" @knife_openstack_create.config[:ssh_port] = "44" @knife_openstack_create.config[:identity_file] = "~/.ssh/key.pem" @knife_openstack_create.config[:chef_node_name] = "blarf" @knife_openstack_create.config[:template_file] = '~/.chef/templates/my-bootstrap.sh.erb' @knife_openstack_create.config[:distro] = 'ubuntu-10.04-magic-sparkles' @knife_openstack_create.config[:first_boot_attributes] = {'some_var' => true} @knife_openstack_create.config[:run_list] = ['role[base]'] @bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server, @new_openstack_server.addresses['public'].last['addr']) end it "should set the bootstrap 'name argument' to the hostname of the OpenStack server" do @bootstrap.name_args.should == ['75.101.253.10'] end it "configures sets the bootstrap's run_list" do @bootstrap.config[:run_list].should == ['role[base]'] end it "configures the bootstrap to use the correct ssh_user login" do @bootstrap.config[:ssh_user].should == 'ubuntu' end it "configures the bootstrap to use the correct ssh_port" do @bootstrap.config[:ssh_port].should == '44' end it "configures the bootstrap to use the correct ssh identity file" do @bootstrap.config[:identity_file].should == "~/.ssh/key.pem" end it "configures the bootstrap to use the configured node name if provided" do @bootstrap.config[:chef_node_name].should == 'blarf' end it "configures the bootstrap to use the server password" do @bootstrap.config[:ssh_password].should == 'password' end it "configures the bootstrap to use the config ssh password" do @knife_openstack_create.config[:ssh_password] = 'testing123' bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server, @new_openstack_server.addresses['public'].last['addr']) bootstrap.config[:ssh_password].should == 'testing123' end it "configures the bootstrap to use the OpenStack server id if no explicit node name is set" do @knife_openstack_create.config[:chef_node_name] = nil bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server, @new_openstack_server.addresses['public'].last['addr']) bootstrap.config[:chef_node_name].should == @new_openstack_server.name end it "configures the bootstrap to use prerelease versions of chef if specified" do @bootstrap.config[:prerelease].should be_false @knife_openstack_create.config[:prerelease] = true bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server, @new_openstack_server.addresses['public'].last['addr']) bootstrap.config[:prerelease].should be_true end it "configures the bootstrap to use the desired distro-specific bootstrap script" do @bootstrap.config[:distro].should == 'ubuntu-10.04-magic-sparkles' end it "configures the bootstrap to use sudo" do @bootstrap.config[:use_sudo].should be_true end it "configures the bootstrap with json attributes" do @bootstrap.config[:first_boot_attributes]['some_var'].should be_true end it "configured the bootstrap to use the desired template" do @bootstrap.config[:template_file].should == '~/.chef/templates/my-bootstrap.sh.erb' end it "configured the bootstrap to set an openstack hint (via Chef::Config)" do Chef::Config[:knife][:hints]['openstack'].should_not be_nil end end describe "when configuring the bootstrap process with private networks" do before do @knife_openstack_create.config[:private_network] = true @bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server, @new_openstack_server.addresses['private'].last['addr']) end it "configures the bootstrap to use private network" do @bootstrap.name_args.should == ['10.251.75.20'] end end describe "when configuring the bootstrap process with alternate networks" do before do @knife_openstack_create.config[:bootstrap_network] = 'foo' @bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server, @new_openstack_server.addresses['foo'].last['addr']) end it "configures the bootstrap to use alternate network" do @bootstrap.name_args.should == ['34.56.78.90'] end end describe "when configuring the bootstrap process with no networks" do before do @knife_openstack_create.config[:network] = false @bootstrap = @knife_openstack_create.bootstrap_for_node(@new_openstack_server, @new_openstack_server.addresses['public'].last['addr']) end it "configures the bootstrap to use public network since none specified" do @bootstrap.name_args.should == ['75.101.253.10'] end end end