%PDF- %PDF-
Direktori : /proc/thread-self/root/lib/python2.7/site-packages/salt/modules/ |
Current File : //proc/thread-self/root/lib/python2.7/site-packages/salt/modules/splunk.py |
# -*- coding: utf-8 -*- ''' Module for interop with the Splunk API .. versionadded:: 2016.3.0. :depends: - splunk-sdk python module :configuration: Configure this module by specifying the name of a configuration profile in the minion config, minion pillar, or master config. The module will use the 'splunk' key by default, if defined. For example: .. code-block:: yaml splunk: username: alice password: abc123 host: example.splunkcloud.com port: 8080 ''' from __future__ import absolute_import, unicode_literals, print_function # Import python libs import logging import hmac import base64 import subprocess # Import 3rd-party libs from salt.ext import six HAS_LIBS = False try: import splunklib.client from splunklib.client import AuthenticationError from splunklib.binding import HTTPError HAS_LIBS = True except ImportError: pass log = logging.getLogger(__name__) __virtualname__ = 'splunk' SERVICE_NAME = "splunk" ALLOWED_FIELDS_FOR_MODIFICATION = [ 'realname', 'roles', 'defaultApp', 'tz', #'capabilities', 'name' ] REQUIRED_FIELDS_FOR_CREATE = [ 'realname', 'name', 'roles' ] def __virtual__(): ''' Only load this module if splunk is installed on this minion. ''' if HAS_LIBS: return __virtualname__ return (False, 'The splunk execution module failed to load: ' 'requires splunk python library to be installed.') def _get_secret_key(profile): config = __salt__['config.option'](profile) return config.get('password_secret_key') def _generate_password(email): m = hmac.new(base64.b64decode(_get_secret_key('splunk')), six.text_type([email, SERVICE_NAME])) return base64.urlsafe_b64encode(m.digest()).strip().replace('=', '') def _send_email(name, email): "send a email to inform user of account creation" config = __salt__['config.option']('splunk') email_object = config.get('email') if email_object: cc = email_object.get('cc') subject = email_object.get('subject') message = email_object.get('message').format(name, name, _generate_password(email), name) try: mail_process = subprocess.Popen(['mail', '-s', subject, '-c', cc, email], stdin=subprocess.PIPE) except Exception as e: log.error("unable to send email to %s: %s", email, e) mail_process.communicate(message) log.info("sent account creation email to %s", email) def _populate_cache(profile="splunk"): config = __salt__['config.option'](profile) key = "splunk.users.{0}".format( config.get('host') ) if key not in __context__: client = _get_splunk(profile) kwargs = {'sort_key': 'realname', 'sort_dir': 'asc'} users = client.users.list(count=-1, **kwargs) result = {} for user in users: result[user.email.lower()] = user __context__[key] = result return True def _get_splunk(profile): ''' Return the splunk client, cached into __context__ for performance ''' config = __salt__['config.option'](profile) key = "splunk.{0}:{1}:{2}:{3}".format( config.get('host'), config.get('port'), config.get('username'), config.get('password') ) if key not in __context__: __context__[key] = splunklib.client.connect( host=config.get('host'), port=config.get('port'), username=config.get('username'), password=config.get('password')) return __context__[key] def list_users(profile="splunk"): ''' List all users in the splunk DB CLI Example: salt myminion splunk.list_users ''' config = __salt__['config.option'](profile) key = "splunk.users.{0}".format( config.get('host') ) if key not in __context__: _populate_cache(profile) return __context__[key] def get_user(email, profile="splunk", **kwargs): ''' Get a splunk user by name/email CLI Example: salt myminion splunk.get_user 'user@example.com' user_details=false salt myminion splunk.get_user 'user@example.com' user_details=true ''' user_map = list_users(profile) user_found = email.lower() in user_map.keys() if not kwargs.get('user_details', False) and user_found: # The user is in splunk group, just return return True elif kwargs.get('user_details', False) and user_found: user = user_map[email.lower()] response = {} for field in ['defaultApp', 'realname', 'name', 'email']: response[field] = user[field] response['roles'] = [] for role in user.role_entities: response['roles'].append(role.name) return response return False def create_user(email, profile="splunk", **kwargs): ''' create a splunk user by name/email CLI Example: salt myminion splunk.create_user user@example.com roles=['user'] realname="Test User" name=testuser ''' client = _get_splunk(profile) email = email.lower() user = list_users(profile).get(email) if user: log.error("User is already present %s", email) return False property_map = {} for field in ALLOWED_FIELDS_FOR_MODIFICATION: if kwargs.get(field): property_map[field] = kwargs.get(field) try: # create for req_field in REQUIRED_FIELDS_FOR_CREATE: if not property_map.get(req_field): log.error("Missing required params %s", ', '.join([six.text_type(k) for k in REQUIRED_FIELDS_FOR_CREATE])) return False newuser = client.users.create(username=property_map['name'], password=_generate_password(email), roles=property_map['roles'], email=email, realname=property_map['realname']) _send_email(newuser.name, newuser.email) response = {} for field in ['email', 'password', 'realname', 'roles']: response[field] = newuser[field] except Exception as e: log.error("Caught exception %s", e) return False def update_user(email, profile="splunk", **kwargs): ''' Create a splunk user by email CLI Example: salt myminion splunk.update_user example@domain.com roles=['user'] realname="Test User" ''' client = _get_splunk(profile) email = email.lower() user = list_users(profile).get(email) if not user: log.error("Failed to retrieve user {0}".format(email)) return False property_map = {} for field in ALLOWED_FIELDS_FOR_MODIFICATION: if kwargs.get(field): property_map[field] = kwargs.get(field) # update kwargs = {} roles = [role.name for role in user.role_entities] for k, v in property_map.items(): resource_value = user[k] if resource_value is not None: # you can't update the username in update api call if k.lower() == 'name': continue if k.lower() == 'roles': if isinstance(v, six.string_types): v = v.split(',') if set(roles) != set(v): kwargs['roles'] = list(set(v)) elif resource_value != v: kwargs[k] = v if len(kwargs) > 0: user.update(**kwargs).refresh() fields_modified = {} for field in ALLOWED_FIELDS_FOR_MODIFICATION: fields_modified[field] = user[field] else: #succeeded, no change return True def delete_user(email, profile="splunk"): ''' Delete a splunk user by email CLI Example: salt myminion splunk_user.delete 'user@example.com' ''' client = _get_splunk(profile) user = list_users(profile).get(email) if user: try: client.users.delete(user.name) except (AuthenticationError, HTTPError) as e: log.info('Exception: %s', e) return False else: return False return user.name not in client.users