class Chef::Knife::SoftlayerServerCreate
Attributes
cci[R]
Public Instance Methods
linux_bootstrap(instance)
click to toggle source
@param [Hash] instance @return [Chef::Knife::Bootstrap]
# File lib/chef/knife/softlayer_server_create.rb, line 383 def linux_bootstrap(instance) bootstrap = Chef::Knife::Bootstrap.new instance.ssh_ip_address = instance.private_ip_address if config[:private_network_only] bootstrap.name_args = [instance.ssh_ip_address] bootstrap.config[:ssh_user] = config[:ssh_user] bootstrap.config[:ssh_password] = config[:ssh_password] if config[:ssh_password] bootstrap.config[:identity_file] = config[:identity_file] if config[:identity_file] bootstrap.config[:ssh_port] = config[:ssh_port] bootstrap.config[:ssh_gateway] = config[:ssh_gateway] bootstrap.config[:chef_node_name] = locate_config_value(:chef_node_name) || instance.id bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root' bootstrap.config[:host_key_verify] = config[:host_key_verify] shared_bootstrap(bootstrap) end
progress(proc)
click to toggle source
# File lib/chef/knife/softlayer_server_create.rb, line 423 def progress(proc) t = Thread.new { Thread.current[:output] = proc.call } i = 0 while t.alive? sleep 0.5 putc('.') i += 1 putc("\n") if i == 76 i = 0 if i == 76 end putc("\n") t.join t[:output] end
run()
click to toggle source
Run the procedure to create a SoftLayer VM and bootstrap it. @return [nil]
# File lib/chef/knife/softlayer_server_create.rb, line 265 def run $stdout.sync = true config.merge!(slurp_from_file(config[:from_file])) if config[:from_file] # TODO: Windows support. raise SoftlayerServerCreateError, "#{ui.color("Windows VMs not currently supported.", :red)}" if config[:os_code] =~ /^WIN_/ raise SoftlayerServerCreateError, "#{ui.color("identity file (-i) option is incompatible with password (-P) option required.", :red)}" if !!config[:identity_file] and !!config[:ssh_password] raise SoftlayerServerCreateError, "#{ui.color("--new-global-ip value must be 'v4' or 'v6'.", :red)}" if config[:new_global_ip] and !config[:new_global_ip].to_s.match(/^v[4,6]$/i) # TODO: create a pre-launch method for clean up tasks. # TODO: create a pre-launch method for clean up tasks. config[:vlan] = config[:vlan].to_i if config[:vlan] config[:private_vlan] = config[:private_vlan].to_i if config[:private_vlan] Fog.credentials[:private_key_path] = config[:identity_file] if config[:identity_file] # TODO: create a pre-launch method for clean up tasks. # TODO: create a pre-launch method for clean up tasks. opts = { :flavor => :flavor_id, :hostname => :name, :domain => nil, :cores => :cpu, :os_code => nil, :ram => nil, :block_storage => :disk, :local_storage => :ephemeral_storage, :datacenter => nil, :ssh_keys => :key_pairs, :vlan => nil, :private_vlan => nil, :image_id => nil, :private_network_only => nil, #:tags => nil, :user_data => nil } opts.keys.each do |opt| if opts[opt].nil? opts[opt] = config[opt] else opts[opts.delete(opt)] = config[opt] # clever shit like this is why I like programming :-] end end # FIXME: make the above deal with nested opts and get rid of this one-off opts[:network_components] = [ {"speed" => config[:nic]} ] if !!config[:nic] opts.delete_if { |k,v| v.nil? } puts ui.color("Launching SoftLayer VM, this may take a few minutes.", :green) instance = connection.servers.create(opts) if config[:private_network_only] || config[:use_private_network] instance.ssh_ip_address = Proc.new {|server| server.private_ip_address } end progress Proc.new { instance.wait_for(timeout=config[:wait_for_timeout].to_i) { ready? and sshable? } } putc("\n") if config[:tags] puts ui.color("Applying tags to SoftLayer instance.", :green) progress Proc.new { instance.add_tags(config[:tags]) } putc("\n") end if config[:new_global_ip] || config[:assign_global_ip] if config[:new_global_ip] # <— the value of this will be v4 or v6 begin puts ui.color('Provisioning new Global IP' + config[:new_global_ip].downcase + ', this may take a few minutes.', :green) create_global_ip = Proc.new do existing_records = connection(:network).get_global_ip_records.body connection(:network).send('create_new_global_ip' + config[:new_global_ip].downcase) or raise SoftlayerServerCreateError, "Unable to create new Global IP Address."; sleep 20 # if we look for the new record too quickly it won't be there yet... new_record_global_id = (connection(:network).get_global_ip_records.body - existing_records).reduce['id'] connection(:network).ips.select { |ip| ip.global_id == new_record_global_id }.reduce end global_ip = progress(create_global_ip) or raise SoftlayerServerCreateError, "Error encountered creating Global IP Address." puts ui.color('Global IP Address successfully created.', :green) rescue SoftlayerServerCreateError => e puts ui.color('We have encountered a problem ordering the requested global IP. The transaction may not have completed.', :red) puts ui.color(e.message, :yellow) end end if config[:assign_global_ip] case config[:assign_global_ip].to_s #ipv4 when /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/ global_ip = connection(:network).ips.by_address(config[:assign_global_ip]) #ipv6 when /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/ global_ip = connection(:network).ips.by_address(config[:assign_global_ip]) else raise SoftlayerServerCreateError, "--assign-global-ip value must be valid IPv4 or IPv6 address" end global_ip or raise SoftlayerServerCreateError, "Global IP address not found. Please check the address or id supplied and try again." global_ip.reload end route_global_ip = Proc.new do puts ui.color('Routing Global IP Address to Instance.', :green) global_ip.route(connection(:network).ips.by_address(instance.public_ip_address)) or raise SoftlayerServerCreateError, "Global IP address failed to route." puts ui.color('Global IP Address has been assigned.', :green) puts ui.color('Global IP Address will not function without networking rules on the endpoint operating system. See http://knowledgelayer.softlayer.com/learning/global-ip-addresses for details.', :yellow) end progress(route_global_ip) end puts ui.color('Bootstrapping Chef node, this may take a few minutes.', :green) linux_bootstrap(instance).run puts ui.color("Applying tags to Chef node.", :green) progress apply_tags(instance) end
slurp_from_file(path)
click to toggle source
# File lib/chef/knife/softlayer_server_create.rb, line 438 def slurp_from_file(path) args = JSON.parse(IO.read(path)) args.keys.each { |key| args[key.gsub('-', '_').to_sym] = args.delete(key) } # TODO: Something less ugly than the empty rescue block below. The :proc Procs/Lambdas aren't idempotent... args.keys.each { |key| begin; args[key] = options[key][:proc] ? options[key][:proc].call(args[key]) : args[key]; rescue; end } args end
windows_bootstrap(server, fqdn)
click to toggle source
# File lib/chef/knife/softlayer_server_create.rb, line 419 def windows_bootstrap(server, fqdn) # TODO: Windows support.... end