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