Fix api_{username,password} and better error message
[p5sagit/Oyster.git] / lib / Oyster / Provision / Rackspace.pm
CommitLineData
c9ecd647 1package Oyster::Provision::Rackspace;
3ded6347 2use Moose::Role;
4bd125ea 3use Net::RackSpace::CloudServers;
4use Net::RackSpace::CloudServers::Server;
5use MIME::Base64;
3ded6347 6
d29be7cc 7# TODO http://failverse.com/manually-creating-a-cloud-server-from-a-cloud-files-image/
8# in order to use an already created image to build the server, a la EC2 way
9
3ded6347 10requires 'config';
11
d6e5f5fe 12has 'api_username' => ( is => 'ro', isa => 'Str', required => 1, lazy => 1, default => sub {
de5283c8 13 my $self = shift;
758d921f 14 return $ENV{CLOUDSERVERS_USER} if exists $ENV{CLOUDSERVERS_USER};
a9e65cee 15 return $self->config->{api_username}
16 or die "Need api_username or CLOUDSERVERS_USER in environment";
d6e5f5fe 17});
8a0402ec 18
d6e5f5fe 19has 'api_password' => ( is => 'ro', isa => 'Str', required => 1, lazy => 1, default => sub {
de5283c8 20 my $self = shift;
758d921f 21 return $ENV{CLOUDSERVERS_KEY} if exists $ENV{CLOUDSERVERS_KEY};
a9e65cee 22 return $self->config->{api_password}
23 or die "Need api_password or CLOUDSERVERS_KEY in environment";
d6e5f5fe 24});
4bd125ea 25
d6e5f5fe 26has '_rs' => ( is => 'rw', isa => 'Net::RackSpace::CloudServers', lazy => 1, default => sub {
4bd125ea 27 my $self = shift;
d6e5f5fe 28 my $rs = eval {
29 Net::RackSpace::CloudServers->new(
30 user => $self->api_username,
31 key => $self->api_password,
32 );
33 };
34 if ( $@ ) {
35 die
36 "Could not instantiate a backend connection to RackSpace CloudServers.\n",
37 "Check the api_username and api_password on the configuration file\n";
38 }
4bd125ea 39 $rs;
40});
41
3ded6347 42sub create {
43 my $self = shift;
44
4bd125ea 45 # Do nothing if the server named $self->name already exists
46 return if scalar grep { $_->name eq $self->name } $self->_rs->get_server();
47
48 # Check the ssh pub key exists and is <10K
370470b2 49 die "SSH pubkey needs to exist" if !-f $self->pub_ssh;
4bd125ea 50 my $pub_ssh = do {
51 local $/=undef;
52 open my $fh, '<', $self->pub_ssh or die "Cannot open ", $self->pub_ssh, ": $!";
53 my $_data = <$fh>;
54 close $fh or die "Cannot close ", $self->pub_ssh, ": $!";
55 $_data;
56 };
370470b2 57 die "SSH pubkey needs to be < 10KiB" if length $pub_ssh > 10*1024;
4bd125ea 58
59 # Build the server
60 my $server = Net::RackSpace::CloudServers::Server->new(
6895749d 61 cloudservers => $self->_rs,
62 name => $self->name,
63 flavorid => $self->size,
64 imageid => $self->image,
65 personality => [
4bd125ea 66 {
83928564 67 path => '/root/.ssh/authorized_keys',
4bd125ea 68 contents => encode_base64($pub_ssh),
69 },
6895749d 70 ],
4bd125ea 71 );
355db0c8 72 my $newserver = $server->create_server;
73 warn "Server root password: ", $newserver->adminpass, "\n";
4bd125ea 74
9e1b1d26 75 do {
76 $|=1;
77 my @tmpservers = $self->_rs->get_server_detail();
78 $server = ( grep { $_->name eq $self->name } @tmpservers )[0];
79 print "\rServer status: ", ($server->status || '?'), " progress: ", ($server->progress || '?');
80 if ( ( $server->status // '' ) ne 'ACTIVE' ) {
81 print " sleeping..";
82 sleep 2;
83 }
84 } while ( ( $server->status // '' ) ne 'ACTIVE' );
85
2bfa7038 86 warn "Server public IP is: @{$server->public_address}\n";
4bd125ea 87
88 # Connect to server and execute installation routines?
89 # Use Net::SSH?
3ded6347 90}
91
3ded6347 92sub delete {
93 my $self = shift;
94
4bd125ea 95 # Die if the server named $self->name already exists
96 my ($server) = grep { $_->name eq $self->name } $self->_rs->get_server();
370470b2 97 die "No such server: ", $self->name if !$server;
4bd125ea 98
99 # Goodbye cruel user!
100 $server->delete_server();
3ded6347 101}
102
103sub resize {
104 my $self = shift;
105
106 $self->config();
107}
c9ecd647 108
1091;
dd69a60d 110
111__END__
112
113=head1 NAME
114
115Oyster::Provision::Rackspace -- Provision your Oyster on Rackspace
116
117=head1 SYNOPSIS
118
119Use the Rackspace backend on your Oyster configuration file
120
121=head1 REQUIRED PARAMETERS
122
123The following are required to instantiate a backend:
124
125=over
126
4bd125ea 127=item api_username
128
129The rackspace API username, or C<$ENV{RACKSPACE_USER}> will be used if that is
130not given
131
8a0402ec 132=item password
133
134This is your rackspace API Key
4bd125ea 135
136The rackspace API key, or C<$ENV{RACKSPACE_KEY}> will be used if that is not
137given
138
dd69a60d 139=item name
140
141The name of your new/existing rackspace server.
142
143=item size
144
145The size ID of the rackspace server you want to create.
146Use the following incantation to see them:
147
148 perl -MNet::RackSpace::CloudServers -e'
149 $r=Net::RackSpace::CloudServers->new(
150 user=>$ENV{CLOUDSERVERS_USER},
151 key=>$ENV{CLOUDSERVERS_KEY},
152 );
153 print map
154 { "id $_->{id} ram $_->{ram} disk $_->{disk}\n" }
155 $r->get_flavor_detail
156 '
157 id 1 ram 256 disk 10
158 id 2 ram 512 disk 20
159 id 3 ram 1024 disk 40
160 id 4 ram 2048 disk 80
161 id 5 ram 4096 disk 160
162 id 6 ram 8192 disk 320
163 id 7 ram 15872 disk 620
164
165=item image
166
167The image ID of the rackspace server you want to create.
168Use the following incantation to see them:
169
170 perl -MNet::RackSpace::CloudServers -e'
171 $r=Net::RackSpace::CloudServers->new(
172 user=>$ENV{CLOUDSERVERS_USER},
173 key=>$ENV{CLOUDSERVERS_KEY},
174 );
175 print map
176 { "id $_->{id} name $_->{name}\n" }
177 $r->get_image_detail
178 '
179 id 29 name Windows Server 2003 R2 SP2 x86
180 id 69 name Ubuntu 10.10 (maverick)
181 id 41 name Oracle EL JeOS Release 5 Update 3
182 id 40 name Oracle EL Server Release 5 Update 4
183 id 187811 name CentOS 5.4
184 id 4 name Debian 5.0 (lenny)
185 id 10 name Ubuntu 8.04.2 LTS (hardy)
186 id 23 name Windows Server 2003 R2 SP2 x64
187 id 24 name Windows Server 2008 SP2 x64
188 id 49 name Ubuntu 10.04 LTS (lucid)
189 id 14362 name Ubuntu 9.10 (karmic)
190 id 62 name Red Hat Enterprise Linux 5.5
191 id 53 name Fedora 13
192 id 17 name Fedora 12
193 id 71 name Fedora 14
194 id 31 name Windows Server 2008 SP2 x86
195 id 51 name CentOS 5.5
196 id 14 name Red Hat Enterprise Linux 5.4
197 id 19 name Gentoo 10.1
198 id 28 name Windows Server 2008 R2 x64
199 id 55 name Arch 2010.05
200
201Oyster only supports Linux images, specifically
202Ubuntu 10.10 (maverick).
203
204=item pub_ssh
205
206The public ssh key you would like copied to the
207new server's C</root/.ssh/authorized_keys> file
208to allow you to ssh in the box without providing
209a root password.
210
211=back
212
213=cut