mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
digitalocean supports bootstrap
This commit is contained in:
parent
8dee42d23b
commit
e47f95b5f9
8 changed files with 84 additions and 18 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -21,3 +21,4 @@ pkg
|
||||||
spec/credentials.yml
|
spec/credentials.yml
|
||||||
vendor/*
|
vendor/*
|
||||||
tags
|
tags
|
||||||
|
tests/digitalocean/fixtures/
|
||||||
|
|
|
@ -16,9 +16,11 @@ module Fog
|
||||||
attribute :flavor_id, :aliases => 'size_id'
|
attribute :flavor_id, :aliases => 'size_id'
|
||||||
# Not documented in their API, but
|
# Not documented in their API, but
|
||||||
# available nevertheless
|
# available nevertheless
|
||||||
attribute :ip_address
|
attribute :public_ip_address, :aliases => 'ip_address'
|
||||||
attribute :backups_active
|
attribute :backups_active
|
||||||
|
|
||||||
|
attr_writer :ssh_keys
|
||||||
|
|
||||||
# Reboot the server (soft reboot).
|
# Reboot the server (soft reboot).
|
||||||
#
|
#
|
||||||
# The preferred method of rebooting a server.
|
# The preferred method of rebooting a server.
|
||||||
|
@ -72,6 +74,25 @@ module Fog
|
||||||
service.power_on_server self.id
|
service.power_on_server self.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def setup(credentials = {})
|
||||||
|
requires :public_ip_address
|
||||||
|
require 'net/ssh'
|
||||||
|
|
||||||
|
commands = [
|
||||||
|
%{mkdir .ssh},
|
||||||
|
%{passwd -l #{username}},
|
||||||
|
%{echo "#{Fog::JSON.encode(Fog::JSON.sanitize(attributes))}" >> ~/attributes.json}
|
||||||
|
]
|
||||||
|
if public_key
|
||||||
|
commands << %{echo "#{public_key}" >> ~/.ssh/authorized_keys}
|
||||||
|
end
|
||||||
|
|
||||||
|
# wait for aws to be ready
|
||||||
|
wait_for { sshable?(credentials) }
|
||||||
|
|
||||||
|
Fog::SSH.new(public_ip_address, username, credentials).run(commands)
|
||||||
|
end
|
||||||
|
|
||||||
# Creates the server (not to be called directly).
|
# Creates the server (not to be called directly).
|
||||||
#
|
#
|
||||||
# Usually called by Fog::Collection#create
|
# Usually called by Fog::Collection#create
|
||||||
|
@ -94,6 +115,8 @@ module Fog
|
||||||
options = {}
|
options = {}
|
||||||
if attributes[:ssh_key_ids]
|
if attributes[:ssh_key_ids]
|
||||||
options[:ssh_key_ids] = attributes[:ssh_key_ids]
|
options[:ssh_key_ids] = attributes[:ssh_key_ids]
|
||||||
|
elsif @ssh_keys
|
||||||
|
options[:ssh_key_ids] = @ssh_keys.map(&:id)
|
||||||
end
|
end
|
||||||
data = service.create_server name,
|
data = service.create_server name,
|
||||||
flavor_id,
|
flavor_id,
|
||||||
|
|
|
@ -6,16 +6,39 @@ module Fog
|
||||||
class DigitalOcean
|
class DigitalOcean
|
||||||
|
|
||||||
class Servers < Fog::Collection
|
class Servers < Fog::Collection
|
||||||
|
|
||||||
model Fog::Compute::DigitalOcean::Server
|
model Fog::Compute::DigitalOcean::Server
|
||||||
|
|
||||||
def all(filters = {})
|
def all(filters = {})
|
||||||
load service.list_servers.body['droplets']
|
data = service.list_servers.body['droplets']
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def bootstrap(new_attributes = {})
|
||||||
|
server = new(new_attributes)
|
||||||
|
|
||||||
|
raise(ArgumentError, "public_key_path is required to configure the server.") unless new_attributes[:public_key_path]
|
||||||
|
raise(ArgumentError, "private_key_path is required to configure the server.") unless new_attributes[:private_key_path]
|
||||||
|
credential = Fog.respond_to?(:credential) && Fog.credential || :default
|
||||||
|
name = "fog_#{credential}"
|
||||||
|
ssh_key = service.ssh_keys.detect { |key| key.name == name }
|
||||||
|
if ssh_key.nil?
|
||||||
|
ssh_key = service.ssh_keys.create(
|
||||||
|
:name => name,
|
||||||
|
:ssh_pub_key => File.read(new_attributes[:public_key_path])
|
||||||
|
)
|
||||||
|
end
|
||||||
|
server.ssh_keys = [ssh_key]
|
||||||
|
|
||||||
|
server.save
|
||||||
|
server.wait_for { ready? }
|
||||||
|
server.setup :keys => [new_attributes[:private_key_path]]
|
||||||
|
server
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(id)
|
def get(id)
|
||||||
if server = service.get_server_details(id).body['droplet']
|
server = service.get_server_details(id).body['droplet']
|
||||||
new server
|
new(server) if server
|
||||||
end
|
|
||||||
rescue Fog::Errors::NotFound
|
rescue Fog::Errors::NotFound
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,9 +15,8 @@ module Fog
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(uri)
|
def get(uri)
|
||||||
if data = service.get_ssh_key(uri)
|
data = service.get_ssh_key(uri).body['ssh_key']
|
||||||
new(data.body)
|
new(data)
|
||||||
end
|
|
||||||
rescue Fog::Errors::NotFound
|
rescue Fog::Errors::NotFound
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,9 +6,9 @@ module Fog
|
||||||
#
|
#
|
||||||
# FIXME: missing ssh keys support
|
# FIXME: missing ssh keys support
|
||||||
#
|
#
|
||||||
def create_server( name,
|
def create_server( name,
|
||||||
size_id,
|
size_id,
|
||||||
image_id,
|
image_id,
|
||||||
region_id,
|
region_id,
|
||||||
options = {} )
|
options = {} )
|
||||||
|
|
||||||
|
@ -20,9 +20,10 @@ module Fog
|
||||||
}
|
}
|
||||||
|
|
||||||
if options[:ssh_key_ids]
|
if options[:ssh_key_ids]
|
||||||
|
options[:ssh_key_ids] = options[:ssh_key_ids].join(",") if options[:ssh_key_ids].is_a? Array
|
||||||
query_hash[:ssh_key_ids] = options[:ssh_key_ids]
|
query_hash[:ssh_key_ids] = options[:ssh_key_ids]
|
||||||
end
|
end
|
||||||
|
|
||||||
request(
|
request(
|
||||||
:expects => [200],
|
:expects => [200],
|
||||||
:method => 'GET',
|
:method => 'GET',
|
||||||
|
@ -35,9 +36,9 @@ module Fog
|
||||||
|
|
||||||
class Mock
|
class Mock
|
||||||
|
|
||||||
def create_server( name,
|
def create_server( name,
|
||||||
size_id,
|
size_id,
|
||||||
image_id,
|
image_id,
|
||||||
region_id,
|
region_id,
|
||||||
options = {} )
|
options = {} )
|
||||||
response = Excon::Response.new
|
response = Excon::Response.new
|
||||||
|
|
|
@ -16,6 +16,7 @@ Shindo.tests("Fog::Compute[:digitalocean] | server model", ['digitalocean', 'com
|
||||||
test(action) { server.respond_to? action }
|
test(action) { server.respond_to? action }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
tests('have attributes') do
|
tests('have attributes') do
|
||||||
model_attribute_hash = server.attributes
|
model_attribute_hash = server.attributes
|
||||||
attributes = [
|
attributes = [
|
||||||
|
@ -26,7 +27,8 @@ Shindo.tests("Fog::Compute[:digitalocean] | server model", ['digitalocean', 'com
|
||||||
:ip_address,
|
:ip_address,
|
||||||
:flavor_id,
|
:flavor_id,
|
||||||
:region_id,
|
:region_id,
|
||||||
:image_id
|
:image_id,
|
||||||
|
:ssh_keys=
|
||||||
]
|
]
|
||||||
tests("The server model should respond to") do
|
tests("The server model should respond to") do
|
||||||
attributes.each do |attribute|
|
attributes.each do |attribute|
|
||||||
|
@ -34,12 +36,14 @@ Shindo.tests("Fog::Compute[:digitalocean] | server model", ['digitalocean', 'com
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test('#reboot') do
|
test('#reboot') do
|
||||||
pending if Fog.mocking?
|
pending if Fog.mocking?
|
||||||
server.reboot
|
server.reboot
|
||||||
server.wait_for { server.state == 'off' }
|
server.wait_for { server.state == 'off' }
|
||||||
server.state == 'off'
|
server.state == 'off'
|
||||||
end
|
end
|
||||||
|
|
||||||
test('#power_cycle') do
|
test('#power_cycle') do
|
||||||
pending if Fog.mocking?
|
pending if Fog.mocking?
|
||||||
server.wait_for { server.ready? }
|
server.wait_for { server.ready? }
|
||||||
|
@ -47,16 +51,19 @@ Shindo.tests("Fog::Compute[:digitalocean] | server model", ['digitalocean', 'com
|
||||||
server.wait_for { server.state == 'off' }
|
server.wait_for { server.state == 'off' }
|
||||||
server.state == 'off'
|
server.state == 'off'
|
||||||
end
|
end
|
||||||
|
|
||||||
test('#stop') do
|
test('#stop') do
|
||||||
server.stop
|
server.stop
|
||||||
server.wait_for { server.state == 'off' }
|
server.wait_for { server.state == 'off' }
|
||||||
server.state == 'off'
|
server.state == 'off'
|
||||||
end
|
end
|
||||||
|
|
||||||
test('#start') do
|
test('#start') do
|
||||||
server.start
|
server.start
|
||||||
server.wait_for { ready? }
|
server.wait_for { ready? }
|
||||||
server.ready?
|
server.ready?
|
||||||
end
|
end
|
||||||
|
|
||||||
# DigitalOcean shutdown is unreliable
|
# DigitalOcean shutdown is unreliable
|
||||||
# so disable it in real mode for now
|
# so disable it in real mode for now
|
||||||
test('#shutdown') do
|
test('#shutdown') do
|
||||||
|
@ -67,6 +74,7 @@ Shindo.tests("Fog::Compute[:digitalocean] | server model", ['digitalocean', 'com
|
||||||
server.wait_for { server.state == 'off' }
|
server.wait_for { server.state == 'off' }
|
||||||
server.state == 'off'
|
server.state == 'off'
|
||||||
end
|
end
|
||||||
|
|
||||||
test('#update') do
|
test('#update') do
|
||||||
begin
|
begin
|
||||||
server.update
|
server.update
|
||||||
|
@ -74,11 +82,11 @@ Shindo.tests("Fog::Compute[:digitalocean] | server model", ['digitalocean', 'com
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# restore server state
|
# restore server state
|
||||||
server.start
|
server.start
|
||||||
|
server.wait_for { ready? }
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -9,4 +9,13 @@ Shindo.tests('Fog::Compute[:digitalocean] | servers collection', ['digitalocean'
|
||||||
@instance.wait_for { ready? }
|
@instance.wait_for { ready? }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
tests("#bootstrap").succeeds do
|
||||||
|
pending if Fog.mocking?
|
||||||
|
@server = service.servers.bootstrap({
|
||||||
|
:public_key_path => File.join(File.dirname(__FILE__), '../../fixtures/id_rsa.pub'),
|
||||||
|
:private_key_path => File.join(File.dirname(__FILE__), '../../fixtures/id_rsa')
|
||||||
|
}.merge(options))
|
||||||
|
end
|
||||||
|
|
||||||
|
@server.destroy if @server
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,7 +19,9 @@ Shindo.tests('Fog::Compute[:digitalocean] | ssh_keys collection', ['digitalocean
|
||||||
|
|
||||||
tests('should be able to get a model') do
|
tests('should be able to get a model') do
|
||||||
test('by instance id') do
|
test('by instance id') do
|
||||||
service.ssh_keys.get(key.id).kind_of? Fog::Compute::DigitalOcean::SshKey
|
retrieved_key = service.ssh_keys.get(key.id)
|
||||||
|
test { retrieved_key.kind_of? Fog::Compute::DigitalOcean::SshKey }
|
||||||
|
test { retrieved_key.name == key.name }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue