remove Stormpath module, states and docs

This commit is contained in:
David Boucha 2017-08-14 16:03:00 -06:00
parent ed7430d91b
commit 0ceb8009c7
13 changed files with 2 additions and 738 deletions

View File

@ -19,5 +19,4 @@ auth modules
pki
rest
sharedsecret
stormpath
yubico

View File

@ -1,6 +0,0 @@
===================
salt.auth.stormpath
===================
.. automodule:: salt.auth.stormpath
:members:

View File

@ -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

View File

@ -399,7 +399,6 @@ execution modules
state
status
statuspage
stormpath
supervisord
suse_apache
svn

View File

@ -1,6 +0,0 @@
======================
salt.modules.stormpath
======================
.. automodule:: salt.modules.stormpath
:members:

View File

@ -250,7 +250,6 @@ state modules
stateconf
status
statuspage
stormpath_account
supervisord
svn
sysctl

View File

@ -1,6 +0,0 @@
=============================
salt.states.stormpath_account
=============================
.. automodule:: salt.states.stormpath_account
:members:

View File

@ -777,8 +777,6 @@ Stateconf
stderr
stdin
stdout
stormpath
Stormpath
str
strftime
subfolder

View File

@ -28,9 +28,8 @@ Tutorials Index
* :ref:`States tutorial, part 3 - Templating, Includes, Extends <tutorial-states-part-3>`
* :ref:`States tutorial, part 4 <tutorial-states-part-4>`
* :ref:`How to Convert Jinja Logic to an Execution Module <tutorial-jinja_to_execution-module>`
* :ref:`Using Salt with Stormpath <tutorial-stormpath>`
* :ref:`Syslog-ng usage <syslog-ng-sate-usage>`
* :ref:`The macOS (Maverick) Developer Step By Step Guide To Salt Installation <tutorial-macos-walk-through>`
* :ref:`SaltStack Walk-through <tutorial-salt-walk-through>`
* :ref:`Writing Salt Tests <tutorial-salt-testing>`
* :ref:`Multi-cloud orchestration with Apache Libcloud <tutorial-libcloud>`
* :ref:`Multi-cloud orchestration with Apache Libcloud <tutorial-libcloud>`

View File

@ -1,198 +0,0 @@
.. _tutorial-stormpath:
=========================
Using Salt with Stormpath
=========================
`Stormpath <https://stormpath.com/>`_ 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
<https://api.stormpath.com/ui2/index.html#/>`_`.
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 <directory_id> 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 <account_id>
salt myminion stormpath.show_account email=<email> directory_id=<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 <account_id> givenName shemp
salt myminion stormpath.update_account <account_id> 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 <account_id> items='{"givenName": "Shemp"}
salt myminion stormpath.update_account <account_id> 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 <account_id>
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.

View File

@ -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 <directory_id> 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 <account_id>
'''
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 <account_id> givenName shemp
salt myminion stormpath.update_account <account_id> middleName ''
salt myminion stormpath.update_account <account_id> items='{"givenName": "Shemp"}
salt myminion stormpath.update_account <account_id> 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 <account_id>
'''
_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', {})]

View File

@ -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

View File

@ -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', {})]