I've been using Digital Ocean for many years for some of my hosting needs. Besides the nice GUI they also have an API and there is a Perl module called DigitalOcean that can be used to access it.
Before you get started you need to generate a new Token.
Create a file called .env with the following content:
DIGITAL_OCEAN_TOKEN = THE_TOKEN
replacing THE_TOKEN by the token you generated.
Install the DigitalOcean and the Dotenv modules:
cpanm DigitalOcean Dotenv
List available images
This is a short example to list the available images:
examples/digitalocean/list_images.pl
use strict;
use warnings;
use 5.010;
use Dotenv;
use DigitalOcean;
use Data::Dumper qw(Dumper);
Dotenv->load;
my $token = $ENV{DIGITAL_OCEAN_TOKEN};
my $do = DigitalOcean->new(oauth_token => $token, wait_on_actions => 1);
my $collection = $do->images;
while (my $obj = $collection->next) {
#say $obj;
#say Dumper $obj;
printf "%s %s\n", $obj->slug, $obj->name;
}
CLI
This is a longer example that will make it easy for you to list images, sizes, regions, ssh keys, or existing droplets.
It also allows you to create a new droplet. (That part currently has hard-coded values.)
This is currently primarily an experimental demo.
examples/digitalocean/digitalocean.pl
use strict;
use warnings;
use DigitalOcean;
use Data::Dumper qw(Dumper);
use Getopt::Long qw(GetOptions);
main();
exit();
sub main {
eval {
require Dotenv;
Dotenv->load;
};
my $token = $ENV{DIGITAL_OCEAN_TOKEN};
my $list;
my $dump;
my $create;
my $droplet;
GetOptions(
'token=s' => \$token,
'list=s' => \$list,
'dump' => \$dump,
'droplet=s' => \$droplet,
'create' => \$create,
) or usage();
usage("We need a token") if not $token;
my $do = DigitalOcean->new(oauth_token => $token, wait_on_actions => 1);
if ($list) {
if ($list eq 'sizes') {
# TODO could we easily sort them by name or by size or by price?
list($do->sizes, $dump, ['slug']); # no name method here
} elsif ($list eq 'images') {
list($do->images, $dump, ['slug', 'name']);
} elsif ($list eq 'regions') {
list($do->regions, $dump, ['slug', 'name']);
} elsif ($list eq 'ssh') {
list($do->ssh_keys, $dump, ['name', 'id']);
} elsif ($list eq 'droplets') {
list($do->droplets, $dump, ['name', 'id']);
} else {
usage("Incorrect --list value '$list'");
}
} elsif ($droplet) {
my $droplet_obj = $do->droplet($droplet);
print $droplet_obj->name, "\n";
print $droplet_obj->created_at, "\n";
#print Dumper $droplet_obj->DigitalOcean;
#print Dumper $droplet_obj;
for my $network (@{ $droplet_obj->networks->v4 }) {
print $network->type, "\n";
print $network->ip_address, "\n";
}
} elsif ($create) {
my $size_id = 's-1vcpu-1gb';
my $image_id = 'ubuntu-20-04-x64'; # 72067660 20.04 (LTS) x64';
my $region_id = 'nyc1';
my $ssh_id = '24064194';
# This Will print "going to wait" then "waiting" several times then "comlete"
# TODO how to stop it?
# TODO how to get the IP address and the ssh signature of the server?
# TODO set ssh
my $response = $do->create_droplet(
name => 'demo',
size => $size_id,
image => $image_id,
region => $region_id,
ssh_keys => [$ssh_id],
backups => 0,
ipv6 => 0,
private_networking => 0,
wait_on_event => 1,
);
print Dumper $response;
}
}
sub list {
my ($collection, $dump, $fields) = @_;
while (my $obj = $collection->next) {
if ($dump) {
print Dumper $obj;
exit;
}
my $str = '';
for my $field (@$fields) {
$str .= $obj->$field . ' ';
}
print "$str\n";
}
}
sub usage {
my ($msg) = @_;
print "$msg\n\n" if $msg;
print qq{
Usage: $0
--token TOKEN
--list [sizes|images|regions|ssh|droplets]
--dump Dump the first listed structure and exit
--droplet ID (returned by --list droplets)
--create Create a droplet with fixed definitions
You can supply the token either on the command line or as an environment variable DIGITAL_OCEAN_TOKEN
or by saving it in the .env file as
DIGITAL_OCEAN_TOKEN = <TOKEN>
In this case you also need to install the Dotenv module from CPAN.
};
exit 1;
}