diff --git a/doc/ref/auth/all/index.rst b/doc/ref/auth/all/index.rst index f12d6f28bf..d421efbbe7 100644 --- a/doc/ref/auth/all/index.rst +++ b/doc/ref/auth/all/index.rst @@ -19,5 +19,4 @@ auth modules pki rest sharedsecret - stormpath yubico diff --git a/doc/ref/auth/all/salt.auth.stormpath.rst b/doc/ref/auth/all/salt.auth.stormpath.rst deleted file mode 100644 index ea5e365ffa..0000000000 --- a/doc/ref/auth/all/salt.auth.stormpath.rst +++ /dev/null @@ -1,6 +0,0 @@ -=================== -salt.auth.stormpath -=================== - -.. automodule:: salt.auth.stormpath - :members: \ No newline at end of file diff --git a/doc/ref/cli/salt.rst b/doc/ref/cli/salt.rst index f2fb693a1c..6eaa9e56ff 100644 --- a/doc/ref/cli/salt.rst +++ b/doc/ref/cli/salt.rst @@ -81,7 +81,7 @@ Options Pass in an external authentication medium to validate against. The credentials will be prompted for. The options are `auto`, - `keystone`, `ldap`, `pam`, and `stormpath`. Can be used with the -T + `keystone`, `ldap`, and `pam`. Can be used with the -T option. .. option:: -T, --make-token diff --git a/doc/ref/modules/all/index.rst b/doc/ref/modules/all/index.rst index 5357f968e8..b6aab6d37d 100644 --- a/doc/ref/modules/all/index.rst +++ b/doc/ref/modules/all/index.rst @@ -399,7 +399,6 @@ execution modules state status statuspage - stormpath supervisord suse_apache svn diff --git a/doc/ref/modules/all/salt.modules.stormpath.rst b/doc/ref/modules/all/salt.modules.stormpath.rst deleted file mode 100644 index 708cfb2ab6..0000000000 --- a/doc/ref/modules/all/salt.modules.stormpath.rst +++ /dev/null @@ -1,6 +0,0 @@ -====================== -salt.modules.stormpath -====================== - -.. automodule:: salt.modules.stormpath - :members: diff --git a/doc/ref/states/all/index.rst b/doc/ref/states/all/index.rst index 6f4e1ad4ce..4803648006 100644 --- a/doc/ref/states/all/index.rst +++ b/doc/ref/states/all/index.rst @@ -250,7 +250,6 @@ state modules stateconf status statuspage - stormpath_account supervisord svn sysctl diff --git a/doc/ref/states/all/salt.states.stormpath_account.rst b/doc/ref/states/all/salt.states.stormpath_account.rst deleted file mode 100644 index f361ec2bb7..0000000000 --- a/doc/ref/states/all/salt.states.stormpath_account.rst +++ /dev/null @@ -1,6 +0,0 @@ -============================= -salt.states.stormpath_account -============================= - -.. automodule:: salt.states.stormpath_account - :members: diff --git a/doc/spelling_wordlist.txt b/doc/spelling_wordlist.txt index f2eb2a614b..c097ef1c59 100644 --- a/doc/spelling_wordlist.txt +++ b/doc/spelling_wordlist.txt @@ -777,8 +777,6 @@ Stateconf stderr stdin stdout -stormpath -Stormpath str strftime subfolder diff --git a/doc/topics/tutorials/index.rst b/doc/topics/tutorials/index.rst index cba3acd739..df668bc395 100644 --- a/doc/topics/tutorials/index.rst +++ b/doc/topics/tutorials/index.rst @@ -28,9 +28,8 @@ Tutorials Index * :ref:`States tutorial, part 3 - Templating, Includes, Extends ` * :ref:`States tutorial, part 4 ` * :ref:`How to Convert Jinja Logic to an Execution Module ` -* :ref:`Using Salt with Stormpath ` * :ref:`Syslog-ng usage ` * :ref:`The macOS (Maverick) Developer Step By Step Guide To Salt Installation ` * :ref:`SaltStack Walk-through ` * :ref:`Writing Salt Tests ` -* :ref:`Multi-cloud orchestration with Apache Libcloud ` \ No newline at end of file +* :ref:`Multi-cloud orchestration with Apache Libcloud ` diff --git a/doc/topics/tutorials/stormpath.rst b/doc/topics/tutorials/stormpath.rst deleted file mode 100644 index 34003d5f99..0000000000 --- a/doc/topics/tutorials/stormpath.rst +++ /dev/null @@ -1,198 +0,0 @@ -.. _tutorial-stormpath: - -========================= -Using Salt with Stormpath -========================= - -`Stormpath `_ is a user management and authentication -service. This tutorial covers using SaltStack to manage and take advantage of -Stormpath's features. - -External Authentication ------------------------ -Stormpath can be used for Salt's external authentication system. In order to do -this, the master should be configured with an ``apiid``, ``apikey``, and the ID -of the ``application`` that is associated with the users to be authenticated: - -.. code-block:: yaml - - stormpath: - apiid: 367DFSF4FRJ8767FSF4G34FGH - apikey: FEFREF43t3FEFRe/f323fwer4FWF3445gferWRWEer1 - application: 786786FREFrefreg435fr1 - -.. note:: - These values can be found in the `Stormpath dashboard - `_`. - -Users that are to be authenticated should be set up under the ``stormpath`` -dict under ``external_auth``: - -.. code-block:: yaml - - external_auth: - stormpath: - larry: - - .* - - '@runner' - - '@wheel' - -Keep in mind that while Stormpath defaults the username associated with the -account to the email address, it is better to use a username without an ``@`` -sign in it. - - -Configuring Stormpath Modules ------------------------------ -Stormpath accounts can be managed via either an execution or state module. In -order to use either, a minion must be configured with an API ID and key. - -.. code-block:: yaml - - stormpath: - apiid: 367DFSF4FRJ8767FSF4G34FGH - apikey: FEFREF43t3FEFRe/f323fwer4FWF3445gferWRWEer1 - directory: efreg435fr1786786FREFr - application: 786786FREFrefreg435fr1 - -Some functions in the ``stormpath`` modules can make use of other options. The -following options are also available. - -directory -````````` -The ID of the directory that is to be used with this minion. Many functions -require an ID to be specified to do their work. However, if the ID of a -``directory`` is specified, then Salt can often look up the resource in -question. - -application -``````````` -The ID of the application that is to be used with this minion. Many functions -require an ID to be specified to do their work. However, if the ID of a -``application`` is specified, then Salt can often look up the resource in -question. - - -Managing Stormpath Accounts ---------------------------- -With the ``stormpath`` configuration in place, Salt can be used to configure -accounts (which may be thought of as users) on the Stormpath service. The -following functions are available. - -stormpath.create_account -```````````````````````` -Create an account on the Stormpath service. This requires a ``directory_id`` as -the first argument; it will not be retrieved from the minion configuration. An -``email`` address, ``password``, first name (``givenName``) and last name -(``surname``) are also required. For the full list of other parameters that may -be specified, see: - -http://docs.stormpath.com/rest/product-guide/#account-resource - -When executed with no errors, this function will return the information about -the account, from Stormpath. - -.. code-block:: bash - - salt myminion stormpath.create_account shemp@example.com letmein Shemp Howard - - -stormpath.list_accounts -``````````````````````` -Show all accounts on the Stormpath service. This will return all accounts, -regardless of directory, application, or group. - -.. code-block:: bash - - salt myminion stormpath.list_accounts - ''' - -stormpath.show_account -`````````````````````` -Show the details for a specific Stormpath account. An ``account_id`` is normally -required. However, if am ``email`` is provided instead, along with either a -``directory_id``, ``application_id``, or ``group_id``, then Salt will search the -specified resource to try and locate the ``account_id``. - -.. code-block:: bash - - salt myminion stormpath.show_account - salt myminion stormpath.show_account email= directory_id= - - -stormpath.update_account -```````````````````````` -Update one or more items for this account. Specifying an empty value will clear -it for that account. This function may be used in one of two ways. In order to -update only one key/value pair, specify them in order: - -.. code-block:: bash - - salt myminion stormpath.update_account givenName shemp - salt myminion stormpath.update_account middleName '' - -In order to specify multiple items, they need to be passed in as a dict. From -the command line, it is best to do this as a JSON string: - -.. code-block:: bash - - salt myminion stormpath.update_account items='{"givenName": "Shemp"} - salt myminion stormpath.update_account items='{"middlename": ""} - -When executed with no errors, this function will return the information about -the account, from Stormpath. - - -stormpath.delete_account -```````````````````````` -Delete an account from Stormpath. - -.. code-block:: bash - - salt myminion stormpath.delete_account - - -stormpath.list_directories -`````````````````````````` -Show all directories associated with this tenant. - -.. code-block:: bash - - salt myminion stormpath.list_directories - - -Using Stormpath States ----------------------- -Stormpath resources may be managed using the state system. The following states -are available. - -stormpath_account.present -````````````````````````` -Ensure that an account exists on the Stormpath service. All options that are -available with the ``stormpath.create_account`` function are available here. -If an account needs to be created, then this function will require the same -fields that ``stormpath.create_account`` requires, including the ``password``. -However, if a password changes for an existing account, it will NOT be updated -by this state. - -.. code-block:: yaml - - curly@example.com: - stormpath_account.present: - - directory_id: efreg435fr1786786FREFr - - password: badpass - - firstName: Curly - - surname: Howard - - nickname: curly - -It is advisable to always set a ``nickname`` that is not also an email address, -so that it can be used by Salt's external authentication module. - -stormpath_account.absent -```````````````````````` -Ensure that an account does not exist on Stormpath. As with -``stormpath_account.present``, the ``name`` supplied to this state is the -``email`` address associated with this account. Salt will use this, with or -without the ``directory`` ID that is configured for the minion. However, lookups -will be much faster with a directory ID specified. - diff --git a/salt/modules/stormpath.py b/salt/modules/stormpath.py deleted file mode 100644 index 020d70b44e..0000000000 --- a/salt/modules/stormpath.py +++ /dev/null @@ -1,242 +0,0 @@ -# -*- coding: utf-8 -*- -''' -Support for Stormpath - -.. versionadded:: 2015.8.0 -''' - -# Import python libs -from __future__ import absolute_import, print_function -import json -import logging - -# Import salt libs -import salt.utils.http - -log = logging.getLogger(__name__) - - -def __virtual__(): - ''' - Only load the module if apache is installed - ''' - if not __opts__.get('stormpath', {}).get('apiid', None): - return (False, 'The stormpath execution module failed to load: requires the stormpath:apiid config option to be set.') - if not __opts__.get('stormpath', {}).get('apikey', None): - return (False, 'The stormpath execution module failed to load: requires the stormpath:apikey config option to be set.') - return True - - -def create_account(directory_id, email, password, givenName, surname, **kwargs): - ''' - Create an account - - CLI Examples: - - salt myminion stormpath.create_account shemp@example.com letmein Shemp Howard - - ''' - items = { - 'email': email, - 'password': password, - 'givenName': givenName, - 'surname': surname, - } - items.update(**kwargs) - - status, result = _query( - action='directories', - command='{0}/accounts'.format(directory_id), - data=json.dumps(items), - header_dict={'Content-Type': 'application/json;charset=UTF-8'}, - method='POST', - ) - - comps = result['href'].split('/') - return show_account(comps[-1]) - - -def list_accounts(): - ''' - Show all accounts. - - CLI Example: - - salt myminion stormpath.list_accounts - - ''' - status, result = _query(action='accounts', command='current') - return result - - -def show_account(account_id=None, - email=None, - directory_id=None, - application_id=None, - group_id=None, - **kwargs): - ''' - Show a specific account. - - CLI Example: - - salt myminion stormpath.show_account - - ''' - if account_id: - status, result = _query( - action='accounts', - command=account_id, - ) - return result - - if email: - if not directory_id and not application_id and not group_id: - return {'Error': 'Either a directory_id, application_id, or ' - 'group_id must be specified with an email address'} - if directory_id: - status, result = _query( - action='directories', - command='{0}/accounts'.format(directory_id), - args={'email': email} - ) - elif application_id: - status, result = _query( - action='applications', - command='{0}/accounts'.format(application_id), - args={'email': email} - ) - elif group_id: - status, result = _query( - action='groups', - command='{0}/accounts'.format(group_id), - args={'email': email} - ) - return result - - -def update_account(account_id, key=None, value=None, items=None): - ''' - Update one or more items for this account. Specifying an empty value will - clear it for that account. - - CLI Examples: - - salt myminion stormpath.update_account givenName shemp - salt myminion stormpath.update_account middleName '' - salt myminion stormpath.update_account items='{"givenName": "Shemp"} - salt myminion stormpath.update_account items='{"middlename": ""} - - ''' - if items is None: - if key is None or value is None: - return {'Error': 'At least one key/value pair is required'} - items = {key: value} - - status, result = _query( - action='accounts', - command=account_id, - data=json.dumps(items), - header_dict={'Content-Type': 'application/json;charset=UTF-8'}, - method='POST', - ) - - return show_account(account_id) - - -def delete_account(account_id): - ''' - Delete an account. - - CLI Examples: - - salt myminion stormpath.delete_account - ''' - _query( - action='accounts', - command=account_id, - method='DELETE', - ) - - return True - - -def list_directories(): - ''' - Show all directories. - - CLI Example: - - salt myminion stormpath.list_directories - - ''' - tenant = show_tenant() - tenant_id = tenant.get('href', '').split('/')[-1] - status, result = _query(action='tenants', command='{0}/directories'.format(tenant_id)) - return result - - -def show_tenant(): - ''' - Get the tenant for the login being used. - ''' - status, result = _query(action='tenants', command='current') - return result - - -def _query(action=None, - command=None, - args=None, - method='GET', - header_dict=None, - data=None): - ''' - Make a web call to Stormpath. - ''' - apiid = __opts__.get('stormpath', {}).get('apiid', None) - apikey = __opts__.get('stormpath', {}).get('apikey', None) - path = 'https://api.stormpath.com/v1/' - - if action: - path += action - - if command: - path += '/{0}'.format(command) - - log.debug('Stormpath URL: {0}'.format(path)) - - if not isinstance(args, dict): - args = {} - - if header_dict is None: - header_dict = {} - - if method != 'POST': - header_dict['Accept'] = 'application/json' - - decode = True - if method == 'DELETE': - decode = False - - return_content = None - result = salt.utils.http.query( - path, - method, - username=apiid, - password=apikey, - params=args, - data=data, - header_dict=header_dict, - decode=decode, - decode_type='json', - text=True, - status=True, - opts=__opts__, - ) - log.debug( - 'Stormpath Response Status Code: {0}'.format( - result['status'] - ) - ) - - return [result['status'], result.get('dict', {})] diff --git a/salt/states/stormpath_account.py b/salt/states/stormpath_account.py deleted file mode 100644 index a23f2b057d..0000000000 --- a/salt/states/stormpath_account.py +++ /dev/null @@ -1,193 +0,0 @@ -# -*- coding: utf-8 -*- -''' -Support for Stormpath. - -.. versionadded:: 2015.8.0 -''' - -# Import python libs -from __future__ import absolute_import -import pprint - - -def __virtual__(): - ''' - Only load if the stormpath module is available in __salt__ - ''' - return 'stormpath.create_account' in __salt__ - - -def present(name, **kwargs): - ''' - Ensure that an account is present and properly configured - - name - The email address associated with the Stormpath account - - directory_id - The ID of a directory which the account belongs to. Required. - - password - Required when creating a new account. If specified, it is advisable to - reference the password in another database using an ``sdb://`` URL. - Will NOT update the password if an account already exists. - - givenName - Required when creating a new account. - - surname - Required when creating a new account. - - username - Optional. Must be unique across the owning directory. If not specified, - the username will default to the email field. - - middleName - Optional. - - status - ``enabled`` accounts are able to login to their assigned applications, - ``disabled`` accounts may not login to applications, ``unverified`` - accounts are disabled and have not verified their email address. - - customData. - Optional. Must be specified as a dict. - ''' - # Because __opts__ is not available outside of functions - backend = __opts__.get('backend', False) - if not backend: - backend = 'requests' - - if backend == 'requests': - from requests.exceptions import HTTPError - elif backend == 'urrlib2': - from urllib2 import HTTPError - else: - from tornado.httpclient import HTTPError - - ret = {'name': name, - 'changes': {}, - 'result': None, - 'comment': ''} - info = {} - try: - result = __salt__['stormpath.show_account'](email=name, **kwargs) - if len(result['items']) > 0: - info = result['items'][0] - except HTTPError: - pass - needs_update = {} - if info.get('email', False): - for field in kwargs: - if info.get(field, None) != kwargs[field]: - needs_update[field] = kwargs[field] - del needs_update['directory_id'] - if 'password' in needs_update: - del needs_update['password'] - if len(needs_update.keys()) < 1: - ret['result'] = True - ret['comment'] = 'Stormpath account {0} already exists and is correct'.format(name) - return ret - if __opts__['test']: - if len(needs_update.keys()) < 1: - ret['comment'] = 'Stormpath account {0} needs to be created'.format(name) - else: - if 'password' in needs_update: - needs_update['password'] = '**HIDDEN**' - ret['comment'] = ('Stormpath account {0} needs the following ' - 'fields to be updated: '.format(', '.join(needs_update))) - return ret - if len(needs_update.keys()) < 1: - info = __salt__['stormpath.create_account'](email=name, **kwargs) - comps = info['href'].split('/') - account_id = comps[-1] - ret['changes'] = info - ret['result'] = True - kwargs['password'] = '**HIDDEN**' - ret['comment'] = 'Created account ID {0} ({1}): {2}'.format( - account_id, name, pprint.pformat(kwargs)) - return ret - comps = info['href'].split('/') - account_id = comps[-1] - result = __salt__['stormpath.update_account'](account_id, items=needs_update) - if result.get('href', None): - ret['changes'] = needs_update - ret['result'] = True - if 'password' in needs_update: - needs_update['password'] = '**HIDDEN**' - ret['comment'] = 'Set the following fields for account ID {0} ({1}): {2}'.format( - account_id, name, pprint.pformat(needs_update)) - return ret - else: - ret['result'] = False - ret['comment'] = 'Failed to set the following fields for account ID {0} ({1}): {2}'.format( - account_id, name, pprint.pformat(needs_update)) - return ret - - -def absent(name, directory_id=None): - ''' - Ensure that an account associated with the given email address is absent. - Will search all directories for the account, unless a directory_id is - specified. - - name - The email address of the account to delete. - - directory_id - Optional. The ID of the directory that the account is expected to belong - to. If not specified, then a list of directories will be retrieved, and - each will be scanned for the account. Specifying a directory_id will - therefore cut down on the number of requests to Stormpath, and increase - performance of this state. - ''' - # Because __opts__ is not available outside of functions - backend = __opts__.get('backend', False) - if not backend: - backend = 'requests' - - if backend == 'requests': - from requests.exceptions import HTTPError - elif backend == 'urrlib2': - from urllib2 import HTTPError - else: - from tornado.httpclient import HTTPError - - ret = {'name': name, - 'changes': {}, - 'result': None, - 'comment': ''} - info = {} - if directory_id is None: - dirs = __salt__['stormpath.list_directories']() - for dir_ in dirs.get('items', []): - try: - comps = dir_.get('href', '').split('/') - directory_id = comps[-1] - info = __salt__['stormpath.show_account'](email=name, directory_id=directory_id) - if len(info.get('items', [])) > 0: - info = info['items'][0] - break - except HTTPError: - pass - else: - info = __salt__['stormpath.show_account'](email=name, directory_id=directory_id) - info = info['items'][0] - if 'items' in info: - ret['result'] = True - ret['comment'] = 'Stormpath account {0} already absent'.format(name) - return ret - if __opts__['test']: - ret['comment'] = 'Stormpath account {0} needs to be deleted'.format(name) - return ret - comps = info['href'].split('/') - account_id = comps[-1] - if __salt__['stormpath.delete_account'](account_id): - ret['changes'] = {'deleted': account_id} - ret['result'] = True - ret['comment'] = 'Stormpath account {0} was deleted'.format(name) - return ret - else: - ret['result'] = False - ret['comment'] = 'Failed to delete Stormpath account {0}'.format(name) - return ret diff --git a/salt/utils/stormpath.py b/salt/utils/stormpath.py deleted file mode 100644 index 516e2d57a7..0000000000 --- a/salt/utils/stormpath.py +++ /dev/null @@ -1,79 +0,0 @@ -# -*- coding: utf-8 -*- -''' -Support for Stormpath - -.. versionadded:: 2015.8.0 -''' - -# Import python libs -from __future__ import absolute_import, print_function -import logging - -# Import salt libs -import salt.utils.http - -log = logging.getLogger(__name__) - - -def query(action=None, - command=None, - args=None, - method='GET', - header_dict=None, - data=None, - opts=None): - ''' - Make a web call to Stormpath - - .. versionadded:: 2015.8.0 - ''' - if opts is None: - opts = {} - - apiid = opts.get('stormpath', {}).get('apiid', None) - apikey = opts.get('stormpath', {}).get('apikey', None) - path = 'https://api.stormpath.com/v1/' - - if action: - path += action - - if command: - path += '/{0}'.format(command) - - log.debug('Stormpath URL: {0}'.format(path)) - - if not isinstance(args, dict): - args = {} - - if header_dict is None: - header_dict = {} - - if method != 'POST': - header_dict['Accept'] = 'application/json' - - decode = True - if method == 'DELETE': - decode = False - - return_content = None - result = salt.utils.http.query( - path, - method, - username=apiid, - password=apikey, - params=args, - data=data, - header_dict=header_dict, - decode=decode, - decode_type='json', - text=True, - status=True, - opts=opts, - ) - log.debug( - 'Stormpath Response Status Code: {0}'.format( - result['status'] - ) - ) - - return [result['status'], result.get('dict', {})]