File: //usr/lib/python2.7/site-packages/salt/states/grafana4_org.py
# -*- coding: utf-8 -*-
'''
Manage Grafana v4.0 orgs
.. versionadded:: 2017.7.0
:configuration: This state requires a configuration profile to be configured
in the minion config, minion pillar, or master config. The module will use
the 'grafana' key by default, if defined.
Example configuration using basic authentication:
.. code-block:: yaml
grafana:
grafana_url: http://grafana.localhost
grafana_user: admin
grafana_password: admin
grafana_timeout: 3
Example configuration using token based authentication:
.. code-block:: yaml
grafana:
grafana_url: http://grafana.localhost
grafana_token: token
grafana_timeout: 3
.. code-block:: yaml
Ensure foobar org is present:
grafana4_org.present:
- name: foobar
- theme: ""
- home_dashboard_id: 0
- timezone: "utc"
- address1: ""
- address2: ""
- city: ""
- zip_code: ""
- state: ""
- country: ""
'''
from __future__ import absolute_import, print_function, unicode_literals
import salt.utils.dictupdate as dictupdate
from salt.utils.dictdiffer import deep_diff
from requests.exceptions import HTTPError
# Import 3rd-party libs
from salt.ext.six import string_types
def __virtual__():
'''Only load if grafana4 module is available'''
return 'grafana4.get_org' in __salt__
def present(name,
users=None,
theme=None,
home_dashboard_id=None,
timezone=None,
address1=None,
address2=None,
city=None,
zip_code=None,
address_state=None,
country=None,
profile='grafana'):
'''
Ensure that an organization is present.
name
Name of the org.
users
Optional - Dict of user/role associated with the org. Example:
.. code-block:: yaml
users:
foo: Viewer
bar: Editor
theme
Optional - Selected theme for the org.
home_dashboard_id
Optional - Home dashboard for the org.
timezone
Optional - Timezone for the org (one of: "browser", "utc", or "").
address1
Optional - address1 of the org.
address2
Optional - address2 of the org.
city
Optional - city of the org.
zip_code
Optional - zip_code of the org.
address_state
Optional - state of the org.
country
Optional - country of the org.
profile
Configuration profile used to connect to the Grafana instance.
Default is 'grafana'.
'''
if isinstance(profile, string_types):
profile = __salt__['config.option'](profile)
ret = {'name': name, 'result': None, 'comment': None, 'changes': {}}
create = False
try:
org = __salt__['grafana4.get_org'](name, profile)
except HTTPError as e:
if e.response.status_code == 404:
create = True
else:
raise
if create:
if __opts__['test']:
ret['comment'] = 'Org {0} will be created'.format(name)
return ret
__salt__['grafana4.create_org'](profile=profile, name=name)
org = __salt__['grafana4.get_org'](name, profile)
ret['changes'] = org
ret['comment'] = 'New org {0} added'.format(name)
data = _get_json_data(address1=address1, address2=address2,
city=city, zipCode=zip_code, state=address_state, country=country,
defaults=org['address'])
if data != org['address']:
if __opts__['test']:
ret['comment'] = 'Org {0} address will be updated'.format(name)
return ret
__salt__['grafana4.update_org_address'](name, profile=profile, **data)
if create:
dictupdate.update(ret['changes']['address'], data)
else:
dictupdate.update(ret['changes'], deep_diff(org['address'], data))
prefs = __salt__['grafana4.get_org_prefs'](name, profile=profile)
data = _get_json_data(theme=theme, homeDashboardId=home_dashboard_id,
timezone=timezone, defaults=prefs)
if data != prefs:
if __opts__['test']:
ret['comment'] = 'Org {0} prefs will be updated'.format(name)
return ret
__salt__['grafana4.update_org_prefs'](name, profile=profile, **data)
if create:
dictupdate.update(ret['changes'], data)
else:
dictupdate.update(ret['changes'], deep_diff(prefs, data))
if users:
db_users = {}
for item in __salt__['grafana4.get_org_users'](name, profile=profile):
db_users[item['login']] = {
'userId': item['userId'],
'role': item['role'],
}
for username, role in users.items():
if username in db_users:
if role is False:
if __opts__['test']:
ret['comment'] = 'Org {0} user {1} will be ' \
'deleted'.format(name, username)
return ret
__salt__['grafana4.delete_org_user'](
db_users[username]['userId'], profile=profile)
elif role != db_users[username]['role']:
if __opts__['test']:
ret['comment'] = 'Org {0} user {1} role will be ' \
'updated'.format(name, username)
return ret
__salt__['grafana4.update_org_user'](
db_users[username]['userId'], loginOrEmail=username,
role=role, profile=profile)
elif role:
if __opts__['test']:
ret['comment'] = 'Org {0} user {1} will be created'.format(
name, username)
return ret
__salt__['grafana4.create_org_user'](
loginOrEmail=username, role=role, profile=profile)
new_db_users = {}
for item in __salt__['grafana4.get_org_users'](name, profile=profile):
new_db_users[item['login']] = {
'userId': item['userId'],
'role': item['role'],
}
if create:
dictupdate.update(ret['changes'], new_db_users)
else:
dictupdate.update(ret['changes'], deep_diff(db_users, new_db_users))
ret['result'] = True
if not create:
if ret['changes']:
ret['comment'] = 'Org {0} updated'.format(name)
else:
ret['changes'] = {}
ret['comment'] = 'Org {0} already up-to-date'.format(name)
return ret
def absent(name, profile='grafana'):
'''
Ensure that a org is present.
name
Name of the org to remove.
profile
Configuration profile used to connect to the Grafana instance.
Default is 'grafana'.
'''
if isinstance(profile, string_types):
profile = __salt__['config.option'](profile)
ret = {'name': name, 'result': None, 'comment': None, 'changes': {}}
org = __salt__['grafana4.get_org'](name, profile)
if not org:
ret['result'] = True
ret['comment'] = 'Org {0} already absent'.format(name)
return ret
if __opts__['test']:
ret['comment'] = 'Org {0} will be deleted'.format(name)
return ret
__salt__['grafana4.delete_org'](org['id'], profile=profile)
ret['result'] = True
ret['changes'][name] = 'Absent'
ret['comment'] = 'Org {0} was deleted'.format(name)
return ret
def _get_json_data(defaults=None, **kwargs):
if defaults is None:
defaults = {}
for k, v in kwargs.items():
if v is None:
kwargs[k] = defaults.get(k)
return kwargs