Repository: ansible/ansible

Issue:
Digital ocean inventory script does not correctly group servers
<!--- Verify first that your issue/request is not already reported in GitHub -->
##### ISSUE TYPE

Bug Report
##### ANSIBLE VERSION

N/A
##### CONFIGURATION

N/A
##### OS / ENVIRONMENT

Mac OSx
##### SUMMARY

The digital ocean inventory script only ever returns a maximum of one server per group.
##### STEPS TO REPRODUCE
- Grab https://github.com/ansible/ansible/blob/devel/contrib/inventory/digital_ocean.py
- Grab and setup https://github.com/ansible/ansible/blob/devel/contrib/inventory/digital_ocean.ini
- Run `python digital_ocean.py  -p`
##### EXPECTED RESULTS

A list of groups with their applicable hosts is shown in json format.
##### ACTUAL RESULTS

Each group only ever has a maximum of one host in it. E.g. I have 20 servers in the lon1 digital ocean region, but the script only outputs

<!--- Paste verbatim command output between quotes below -->

```
 "region_lon1": {
    "hosts": [
      "**ip was here**"
    ], 
    "vars": {}
  }, 
```



Discussion:

Resolving patch:
diff --git a/contrib/inventory/digital_ocean.py b/contrib/inventory/digital_ocean.py
--- a/contrib/inventory/digital_ocean.py
+++ b/contrib/inventory/digital_ocean.py
@@ -145,7 +145,7 @@
     import simplejson as json
 
 try:
-    from dopy.manager import DoError, DoManager
+    from dopy.manager import DoManager
 except ImportError as e:
     print("failed=True msg='`dopy` library required for this script'")
     sys.exit(1)
@@ -351,7 +351,13 @@ def load_from_digital_ocean(self, resource=None):
 
     def build_inventory(self):
         '''Build Ansible inventory of droplets'''
-        self.inventory = {}
+        self.inventory = {
+                            'all': {
+                                    'hosts': [],
+                                    'vars': self.group_variables
+                                   },
+                            '_meta': {'hostvars': {}}
+                        }
 
         # add all droplets by id and name
         for droplet in self.data['droplets']:
@@ -365,24 +371,35 @@ def build_inventory(self):
             else:
                 dest = droplet['ip_address']
 
-            dest = { 'hosts': [ dest ], 'vars': self.group_variables }
+            self.inventory['all']['hosts'].append(dest)
 
             self.inventory[droplet['id']] = dest
             self.inventory[droplet['name']] = dest
-            self.inventory['region_' + droplet['region']['slug']] = dest
-            self.inventory['image_' + str(droplet['image']['id'])] = dest
-            self.inventory['size_' + droplet['size']['slug']] = dest
 
-            image_slug = droplet['image']['slug']
-            if image_slug:
-                self.inventory['image_' + self.to_safe(image_slug)] = dest
-            else:
-                image_name = droplet['image']['name']
-                if image_name:
-                    self.inventory['image_' + self.to_safe(image_name)] = dest
+            # groups that are always present
+            for group in [
+                            'region_' + droplet['region']['slug'],
+                            'image_' + str(droplet['image']['id']),
+                            'size_' + droplet['size']['slug'],
+                            'distro_' + self.to_safe(droplet['image']['distribution']),
+                            'status_' + droplet['status'],
+
+                        ]:
+                if group not in self.inventory:
+                    self.inventory[group] = { 'hosts': [ ], 'vars': {} }
+                self.inventory[group]['hosts'].append(dest)
+
+            # groups that are not always present
+            for group in [
+                            droplet['image']['slug'],
+                            droplet['image']['name']
+                         ]:
+                if group:
+                    image = 'image_' + self.to_safe(group)
+                    if image not in self.inventory:
+                        self.inventory[image] = { 'hosts': [ ], 'vars': {} }
+                    self.inventory[image]['hosts'].append(dest)
 
-            self.inventory['distro_' + self.to_safe(droplet['image']['distribution'])] = dest
-            self.inventory['status_' + droplet['status']] = dest
 
 
     def load_droplet_variables_for_host(self):


Test patch: