3

I'm working on an automation script with the DO API and Ansible. I can create a lot of droplets but how to know if the created droplets has been active?

The first (naive) approach uses the following process:

A. Create droplet with the Digital Ocean API
B. Call the API to get the created droplet informations
    1. is active ?
        yes : 
        no : go to B

In the best world, after the droplet creation, I will be notified (like a webhook executed when the droplet creation is finished). Is it possible?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Anthony
  • 121
  • 7

3 Answers3

4

Looking at the API docs https://developers.digitalocean.com/documentation/v2/

You should be able to see the status of the Droplet (see the droplets section).

Using your logic you could:

  1. Create droplet and store the id in a variable
  2. Sleep 1 Minute
  3. Call the droplet with the id /v2/droplets/$DROPLET_ID.
  4. Test the response status (A status string indicating the state of the Droplet instance. This may be "new", "active", "off", or "archive".).
  5. If status == new do something

UPDATE

Another method would be to modify the droplet as it is created. With Digital ocean you can pass User Data, previously I have used this to configure servers automatically, here is an example.

$user_data = <<<EOD
#!/bin/bash

apt-get update 
apt-get -y install apache2 
apt-get -y install php5 
apt-get -y install php5-mysql 
apt-get -y install unzip 
service apache2 restart 
cd /var/www/html 
mkdir pack 
cd pack 
wget --user {$wgetUser} --password {$wgetPass} http://x.x.x.x/pack.tar.gz
tar -xvf pack.tar.gz 
php update.php
EOD;


    //Start of the droplet creation
    $data = array(
                    "name"=>"AutoRes".$humanProv.strtoupper($lang), 
                    "region"=>randomRegion(), 
                    "size"=>"512mb", 
                    "image"=>"ubuntu-14-04-x64",
                    "ssh_keys"=>$sshKey,
                    "backups"=>false,
                    "ipv6"=>false,
                    "user_data"=>$user_data,
                    "private_networking"=>null,
                    );

    $chDroplet = curl_init('https://api.digitalocean.com/v2/droplets');
    curl_setopt($chDroplet, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($chDroplet, CURLOPT_POSTFIELDS, json_encode($data)  );
    curl_setopt($chDroplet, CURLOPT_HTTPHEADER, array(
        'Authorization: Bearer '.$apiKey,
        'Content-Type: application/json',
        'Content-Length: ' . strlen(json_encode($data)),
    ));

Basically once the droplet is active it will run these commands and then download a tar.gz file from my server and execute it, you could potentially create update.php to call your server and therefore update it that the droplet is online.

The Humble Rat
  • 4,586
  • 6
  • 39
  • 73
  • Thanks for the reply. You describe the first approach but I'm looking for an "event based" solution such as "webhoock". – Anthony Feb 17 '16 at 12:51
  • @Anthony I understand a bit more what you need now. I have put an update to my answer. – The Humble Rat Feb 17 '16 at 13:22
  • That's just perfect ! many thanks for this solution. With this parameter I can run simple **wget** to call my _"webhook"_. I didn't know that _User Data_ can be used to insert code – Anthony Feb 17 '16 at 14:31
  • @Anthony glad I could help. The user data is amazing, it really opens digital ocean up and like I say for my purposes I can deploy 50 servers all automatically configured with one click of a button which feels a long way from my first echo on a page. Happy coding my friend. – The Humble Rat Feb 18 '16 at 08:15
1

For the first approach, DigitalOcean's API also returns Action items. These can be used to check the status of different actions you take. The returned json looks like:

{
  "action": {
    "id": 36804636,
    "status": "completed",
    "type": "create",
    "started_at": "2014-11-14T16:29:21Z",
    "completed_at": "2014-11-14T16:30:06Z",
    "resource_id": 3164444,
    "resource_type": "droplet",
    "region": "nyc3",
    "region_slug": "nyc3"
  }
}

Here is a quick example of how they can be used:

import os, time
import requests

token = os.getenv('DO_TOKEN')
url = "https://api.digitalocean.com/v2/droplets"

payload = {'name': 'example.com', 'region': 'nyc3', 'size': '512mb', "image": "ubuntu-14-04-x64"}
headers = {'Authorization': 'Bearer {}'.format(token)}

r = requests.post(url, headers=headers, json=payload)

action_url = r.json()['links']['actions'][0]['href']

r = requests.get(action_url, headers=headers)
status = r.json()['action']['status']

while status != u'completed':
    print('Waiting for Droplet...')
    time.sleep(2)
    r = requests.get(action_url, headers=headers)
    status = r.json()['action']['status']

print('Droplet ready...')
andrewsomething
  • 2,146
  • 2
  • 18
  • 22
0
# after you define the droplet you want to create,
# this will let you know exactly when the droplet is ready.
# and return its IP address and Active status

...
droplet.create()
    i = 0
    while True:
        actions = droplet.get_actions()
        for action in actions:
            action.load()
            status = action.status
            print(status)        
            if status == "completed":
                print("Droplet created")
                droplets = manager.get_all_droplets(tag_name=[droplet_name"])
                for droplet in droplets:
                    if droplet.name == droplet_name:   
                        while True:
                            if droplet.status == "active":
                                print("Droplet is active")
                                return f"droplet created {droplet_name=} {droplet.ip_address=} {droplet.status=}"
                            else:
                                time.sleep(5)
                                print("Droplet is under creation, waiting for it to be active...")                 
        time.sleep(5)
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83