X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FOyster%2FProvision%2FRackspace.pm;h=f1127d194be408024e978dee4573fd6e904eacb7;hb=e4c303246b11e0ccd6606d601a9c3e5836c95474;hp=7e809931c2c5039f64f034b3984765f8362f7282;hpb=dd69a60d6e91573c5590e98c7cc468a65f47d9d2;p=p5sagit%2FOyster.git diff --git a/lib/Oyster/Provision/Rackspace.pm b/lib/Oyster/Provision/Rackspace.pm index 7e80993..f1127d1 100644 --- a/lib/Oyster/Provision/Rackspace.pm +++ b/lib/Oyster/Provision/Rackspace.pm @@ -1,23 +1,81 @@ package Oyster::Provision::Rackspace; use Moose::Role; - -has 'name' => ( is => 'ro', isa => 'Str', required => 1 ); -has 'size' => ( is => 'ro', isa => 'Str', required => 1 ); -has 'image' => ( is => 'ro', isa => 'Str', required => 1 ); -has 'pub_ssh' => ( is => 'ro', isa => 'Str', required => 1 ); +use Carp; +use Net::RackSpace::CloudServers; +use Net::RackSpace::CloudServers::Server; +use MIME::Base64; requires 'config'; +has 'api_username' => ( is => 'ro', isa => 'Str', required => 1, lazy_build => 1); +sub _build_api_username { + return $ENV{CLOUDSERVERS_USER} if exists $ENV{CLOUDSERVERS_USER}; + confess "Need api_username or CLOUDSERVERS_USER in environment"; +} + +has 'api_password' => ( is => 'ro', isa => 'Str', required => 1, lazy_build => 1); +sub _build_api_password { + return $ENV{CLOUDSERVERS_KEY} if exists $ENV{CLOUDSERVERS_KEY}; + confess "Need api_password or CLOUDSERVERS_KEY in environment"; +} + +has '_rs' => ( is => 'rw', isa => 'Net::RackSpace::CloudServers', default => sub { + my $self = shift; + my $rs = Net::RackSpace::CloudServers->new( + user => $self->api_username, + key => $self->api_password, + ); + $rs; +}); + sub create { my $self = shift; - $self->config(); + # Do nothing if the server named $self->name already exists + return if scalar grep { $_->name eq $self->name } $self->_rs->get_server(); + + # Check the ssh pub key exists and is <10K + confess "SSH pubkey needs to exist" if !-f $self->pub_ssh; + my $pub_ssh = do { + local $/=undef; + open my $fh, '<', $self->pub_ssh or die "Cannot open ", $self->pub_ssh, ": $!"; + my $_data = <$fh>; + close $fh or die "Cannot close ", $self->pub_ssh, ": $!"; + $_data; + }; + confess "SSH pubkey needs to be < 10KiB" if length $pub_ssh > 10*1024; + + # Build the server + my $server = Net::RackSpace::CloudServers::Server->new( + cloudservers => $self->_rs, + name => $self->name, + flavor => $self->size, + image => $self->image, + personality => [ + { + path => $self->pub_ssh, + contents => encode_base64($pub_ssh), + }, + ], + ); + $server->create_server; + + warn "Server public IP is: ", ($server->public_address)[0], "\n"; + warn "Server root password: ", $server->adminpass, "\n"; + + # Connect to server and execute installation routines? + # Use Net::SSH? } sub delete { my $self = shift; - $self->config(); + # Die if the server named $self->name already exists + my ($server) = grep { $_->name eq $self->name } $self->_rs->get_server(); + confess "No such server: ", $self->name if !$server; + + # Goodbye cruel user! + $server->delete_server(); } sub resize { @@ -44,6 +102,18 @@ The following are required to instantiate a backend: =over +=item api_username + +The rackspace API username, or C<$ENV{RACKSPACE_USER}> will be used if that is +not given + +=item password + +This is your rackspace API Key + +The rackspace API key, or C<$ENV{RACKSPACE_KEY}> will be used if that is not +given + =item name The name of your new/existing rackspace server.