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