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