Bring in domains state

Change-Id: I0d8009bb2b295c807f83a290f35a1d962c832624
diff --git a/_states/keystonev3.py b/_states/keystonev3.py
index f9012cf..55d14e9 100644
--- a/_states/keystonev3.py
+++ b/_states/keystonev3.py
@@ -486,6 +486,65 @@
     return _deleted(name, 'role')
 
 
+def domain_present(name, cloud_name, **kwargs):
+
+    domains = _keystonev3_call(
+        'domain_list', name=name, cloud_name=cloud_name)['domains']
+
+    if not domains:
+        try:
+            resp = _keystonev3_call(
+                'domain_create', name=name, cloud_name=cloud_name, **kwargs
+            )
+        except Exception as e:
+            log.error('Keystone domain create failed with {}'.format(e))
+            return _create_failed(name, 'domain')
+        return _created(name, 'domain', resp)
+    elif len(domains) == 1:
+        exact_domain = domains[0]
+        domain_id = exact_domain['id']
+        changable = ('tags', 'enabled', 'description')
+        to_update = {}
+
+        for key in kwargs:
+            if (key in changable and (key not in exact_domain or
+                                      kwargs[key] != exact_domain[key])):
+                to_update[key] = kwargs[key]
+
+        if to_update:
+            try:
+                resp = _keystonev3_call(
+                    'domain_update', domain_id=domain_id,
+                    cloud_name=cloud_name, **to_update
+                )
+            except Exception as e:
+                log.error('Keystone domain update failed with {}'.format(e))
+                return _update_failed(name, 'domain')
+            return _updated(name, 'domain', resp)
+        else:
+            return _no_changes(name, 'domain')
+    else:
+        return _find_failed(name, 'domain')
+
+
+def domain_absent(name, cloud_name):
+    try:
+        _keystonev3_call('domain_get_details',
+                         domain_id=name, cloud_name=cloud_name)
+    except Exception as e:
+        if 'ResourceNotFound' in repr(e):
+            return _absent(name, 'domain')
+        else:
+            log.error('Failed to get a domain {}'.format(e))
+            return _find_failed(name, 'domain')
+    try:
+        _keystonev3_call('domain_delete', domain_id=name,
+                         cloud_name=cloud_name)
+    except Exception:
+        return _delete_failed(name, 'domain')
+    return _deleted(name, 'domain')
+
+
 def _created(name, resource, resource_definition):
     changes_dict = {
         'name': name,