Configure Tower in Tower:

* Add separate Django app for configuration: awx.conf.
* Migrate from existing main.TowerSettings model to conf.Setting.
* Add settings wrapper to allow get/set/del via django.conf.settings.
* Update existing references to tower_settings to use django.conf.settings.
* Add a settings registry to allow for each Django app to register configurable settings.
* Support setting validation and conversion using Django REST Framework fields.
* Add /api/v1/settings/ to display a list of setting categories.
* Add /api/v1/settings/<slug>/ to display all settings in a category as a single object.
* Allow PUT/PATCH to update setting singleton, DELETE to reset to defaults.
* Add "all" category to display all settings across categories.
* Add "changed" category to display only settings configured in the database.
* Support per-user settings via "user" category (/api/v1/settings/user/).
* Support defaults for user settings via "user-defaults" category (/api/v1/settings/user-defaults/).
* Update serializer metadata to support category, category_slug and placeholder on OPTIONS responses.
* Update serializer metadata to handle child fields of a list/dict.
* Hide raw data form in browsable API for OPTIONS and DELETE.
* Combine existing licensing code into single "TaskEnhancer" class.
* Move license helper functions from awx.api.license into awx.conf.license.
* Update /api/v1/config/ to read/verify/update license using TaskEnhancer and settings wrapper.
* Add support for caching settings accessed via settings wrapper.
* Invalidate cached settings when Setting model changes or is deleted.
* Preload all database settings into cache on first access via settings wrapper.
* Add support for read-only settings than can update their value depending on other settings.
* Use setting_changed signal whenever a setting changes.
* Register configurable authentication, jobs, system and ui settings.
* Register configurable LDAP, RADIUS and social auth settings.
* Add custom fields and validators for URL, LDAP, RADIUS and social auth settings.
* Rewrite existing validator for Credential ssh_private_key to support validating private keys, certs or combinations of both.
* Get all unit/functional tests working with above changes.
* Add "migrate_to_database_settings" command to determine settings to be migrated into the database and comment them out when set in Python settings files.
* Add support for migrating license key from file to database.
* Remove database-configuable settings from local_settings.py example files.
* Update setup role to no longer install files for database-configurable settings.

f 94ff6ee More settings work.
f af4c4e0 Even more db settings stuff.
f 96ea9c0 More settings, attempt at singleton serializer for settings.
f 937c760 More work on singleton/category views in API, add code to comment out settings in Python files, work on command to migrate settings to database.
f 425b0d3 Minor fixes for sprint demo.
f ea402a4 Add support for read-only settings, cleanup license engine, get license support working with DB settings.
f ec289e4 Rename migration, minor fixmes, update setup role.
f 603640b Rewrite key/cert validator, finish adding social auth fields, hook up signals for setting_changed, use None to imply a setting is not set.
f 67d1b5a Get functional/unit tests passing.
f 2919b62 Flake8 fixes.
f e62f421 Add redbaron to requirements, get file to database migration working (except for license).
f c564508 Add support for migrating license file.
f 982f767 Add support for regex in social map fields.
This commit is contained in:
Chris Church
2016-09-26 22:14:47 -04:00
parent 609a3e6f2f
commit 6ebe45b1bd
92 changed files with 4401 additions and 1791 deletions

View File

@@ -156,141 +156,13 @@ LOGGING['handlers']['syslog'] = {
#LOGGING['loggers']['awx.main.signals']['propagate'] = True
#LOGGING['loggers']['awx.main.permissions']['propagate'] = True
# Enable the following line to turn on database settings logging.
#LOGGING['loggers']['awx.conf']['level'] = 'DEBUG'
# Enable the following lines to turn on LDAP auth logging.
#LOGGING['loggers']['django_auth_ldap']['handlers'] = ['console']
#LOGGING['loggers']['django_auth_ldap']['level'] = 'DEBUG'
###############################################################################
# LDAP AUTHENTICATION SETTINGS
###############################################################################
# Refer to django-auth-ldap docs for more details:
# http://pythonhosted.org/django-auth-ldap/authentication.html
# Imports needed for LDAP configuration.
import ldap
from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion
from django_auth_ldap.config import ActiveDirectoryGroupType
# LDAP server URI, such as "ldap://ldap.example.com:389" (non-SSL) or
# "ldaps://ldap.example.com:636" (SSL). LDAP authentication is disable if this
# parameter is empty.
AUTH_LDAP_SERVER_URI = ''
# DN of user to bind for all search queries. Normally in the format
# "CN=Some User,OU=Users,DC=example,DC=com" but may also be specified as
# "DOMAIN\username" for Active Directory.
AUTH_LDAP_BIND_DN = ''
# Password using to bind above user account.
AUTH_LDAP_BIND_PASSWORD = ''
# Enable TLS when the connection is not using SSL.
AUTH_LDAP_START_TLS = False
# Additional options to set for the LDAP connection. LDAP referrals are
# disabled by default (to prevent certain LDAP queries from hanging with AD).
AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_REFERRALS: 0,
}
# LDAP search query to find users.
AUTH_LDAP_USER_SEARCH = LDAPSearch(
'OU=Users,DC=example,DC=com', # Base DN
ldap.SCOPE_SUBTREE, # SCOPE_BASE, SCOPE_ONELEVEL, SCOPE_SUBTREE
'(sAMAccountName=%(user)s)', # Query
)
# Alternative to user search, if user DNs are all of the same format.
#AUTH_LDAP_USER_DN_TEMPLATE = 'uid=%(user)s,OU=Users,DC=example,DC=com'
# Mapping of LDAP to user atrributes (key is user attribute name, value is LDAP
# attribute name).
AUTH_LDAP_USER_ATTR_MAP = {
'first_name': 'givenName',
'last_name': 'sn',
'email': 'mail',
}
# LDAP search query to find groups. Does not support LDAPSearchUnion.
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
'DC=example,DC=com', # Base DN
ldap.SCOPE_SUBTREE, # SCOPE_BASE, SCOPE_ONELEVEL, SCOPE_SUBTREE
'(objectClass=group)', # Query
)
# Type of group returned by the search above. Should be one of the types
# listed at: http://pythonhosted.org/django-auth-ldap/groups.html#types-of-groups
AUTH_LDAP_GROUP_TYPE = ActiveDirectoryGroupType()
# Group DN required to login. If specified, user must be a member of this
# group to login via LDAP.
#AUTH_LDAP_REQUIRE_GROUP = ''
# Group DN denied from login. If specified, user will not be allowed to login
# if a member of this group.
#AUTH_LDAP_DENY_GROUP = ''
# User profile flags updated from group membership (key is user attribute name,
# value is group DN).
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
#'is_superuser': 'CN=Domain Admins,CN=Users,DC=example,DC=com',
}
# Mapping between organization admins/users and LDAP groups. Keys are
# organization names (will be created if not present). Values are dictionaries
# of options for each organization's membership, where each can contain the
# following parameters:
# - remove: True/False. Defaults to False. Specifies the default for
# remove_admins or remove_users if those parameters aren't explicitly set.
# - admins: None, True/False, string or list/tuple of strings.
# If None, organization admins will not be updated.
# If True/False, all LDAP users will be added/removed as admins.
# If a string or list of strings, specifies the group DN(s). User will be
# added as an org admin if the user is a member of ANY of these groups.
# - remove_admins: True/False. Defaults to False. If True, a user who is not a
# member of the given groups will be removed from the organization's admins.
# - users: None, True/False, string or list/tuple of strings. Same rules apply
# as for admins.
# - remove_users: True/False. Defaults to False. If True, a user who is not a
# member of the given groups will be removed from the organization's users.
AUTH_LDAP_ORGANIZATION_MAP = {
#'Test Org': {
# 'admins': 'CN=Domain Admins,CN=Users,DC=example,DC=com',
# 'users': ['CN=Domain Users,CN=Users,DC=example,DC=com'],
#},
#'Test Org 2': {
# 'admins': ['CN=Administrators,CN=Builtin,DC=example,DC=com'],
# 'users': True,
#},
}
# Mapping between team members (users) and LDAP groups. Keys are team names
# (will be created if not present). Values are dictionaries of options for
# each team's membership, where each can contain the following parameters:
# - organization: string. The name of the organization to which the team
# belongs. The team will be created if the combination of organization and
# team name does not exist. The organization will first be created if it
# does not exist.
# - users: None, True/False, string or list/tuple of strings.
# If None, team members will not be updated.
# If True/False, all LDAP users will be added/removed as team members.
# If a string or list of strings, specifies the group DN(s). User will be
# added as a team member if the user is a member of ANY of these groups.
# - remove: True/False. Defaults to False. If True, a user who is not a member
# of the given groups will be removed from the team.
AUTH_LDAP_TEAM_MAP = {
'My Team': {
'organization': 'Test Org',
'users': ['CN=Domain Users,CN=Users,DC=example,DC=com'],
'remove': True,
},
'Other Team': {
'organization': 'Test Org 2',
'users': 'CN=Other Users,CN=Users,DC=example,DC=com',
'remove': False,
},
}
###############################################################################
# SCM TEST SETTINGS
###############################################################################
@@ -329,280 +201,6 @@ import getpass
TEST_SSH_LOOPBACK_USERNAME = getpass.getuser()
TEST_SSH_LOOPBACK_PASSWORD = ''
###############################################################################
# LDAP TEST SETTINGS
###############################################################################
# LDAP connection and authentication settings for unit tests only. LDAP tests
# will be skipped if TEST_AUTH_LDAP_SERVER_URI is not configured.
TEST_AUTH_LDAP_SERVER_URI = ''
TEST_AUTH_LDAP_BIND_DN = ''
TEST_AUTH_LDAP_BIND_PASSWORD = ''
TEST_AUTH_LDAP_START_TLS = False
TEST_AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_REFERRALS: 0,
}
# LDAP username/password for testing authentication.
TEST_AUTH_LDAP_USERNAME = ''
TEST_AUTH_LDAP_PASSWORD = ''
# LDAP search query to find users.
TEST_AUTH_LDAP_USER_SEARCH = LDAPSearch(
'CN=Users,DC=example,DC=com',
ldap.SCOPE_SUBTREE,
'(sAMAccountName=%(user)s)',
)
# Alternative to user search.
#TEST_AUTH_LDAP_USER_DN_TEMPLATE = 'sAMAccountName=%(user)s,OU=Users,DC=example,DC=com'
# Mapping of LDAP attributes to user attributes.
TEST_AUTH_LDAP_USER_ATTR_MAP = {
'first_name': 'givenName',
'last_name': 'sn',
'email': 'mail',
}
# LDAP search query for finding groups.
TEST_AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
'DC=example,DC=com',
ldap.SCOPE_SUBTREE,
'(objectClass=group)',
)
# Type of group returned by the search above.
TEST_AUTH_LDAP_GROUP_TYPE = ActiveDirectoryGroupType()
# Test DNs for a group required to login. User should be a member of the first
# group, but not a member of the second.
TEST_AUTH_LDAP_REQUIRE_GROUP = 'CN=Domain Admins,CN=Users,DC=example,DC=com'
TEST_AUTH_LDAP_REQUIRE_GROUP_FAIL = 'CN=Guest,CN=Users,DC=example,DC=com'
# Test DNs for a group denied from login. User should not be a member of the
# first group, but should be a member of the second.
TEST_AUTH_LDAP_DENY_GROUP = 'CN=Guest,CN=Users,DC=example,DC=com'
TEST_AUTH_LDAP_DENY_GROUP_FAIL = 'CN=Domain Admins,CN=Users,DC=example,DC=com'
# User profile flags updated from group membership. Test user should be a
# member of the group.
TEST_AUTH_LDAP_USER_FLAGS_BY_GROUP = {
'is_superuser': 'CN=Domain Admins,CN=Users,DC=example,DC=com',
}
# Test mapping between organization admins/users and LDAP groups.
TEST_AUTH_LDAP_ORGANIZATION_MAP = {
'Test Org': {
'admins': 'CN=Domain Admins,CN=Users,DC=example,DC=com',
'users': ['CN=Domain Users,CN=Users,DC=example,DC=com'],
},
'Test Org 2': {
'admins': ['CN=Administrators,CN=Builtin,DC=example,DC=com'],
'users': True,
},
}
# Expected results from organization mapping. After login, should user be an
# admin/user in the given organization?
TEST_AUTH_LDAP_ORGANIZATION_MAP_RESULT = {
'Test Org': {'admins': True, 'users': False},
'Test Org 2': {'admins': False, 'users': True},
}
# Second test mapping to test remove parameters.
TEST_AUTH_LDAP_ORGANIZATION_MAP_2 = {
'Test Org': {
'admins': 'CN=Domain Users,CN=Users,DC=example,DC=com',
'users': True,
'remove_admins': True,
'remove_users': False,
},
'Test Org 2': {
'admins': ['CN=Domain Admins,CN=Users,DC=example,DC=com',
'CN=Administrators,CN=Builtin,DC=example,DC=com'],
'users': False,
'remove': True,
},
}
# Expected results from second organization mapping.
TEST_AUTH_LDAP_ORGANIZATION_MAP_2_RESULT = {
'Test Org': {'admins': False, 'users': True},
'Test Org 2': {'admins': True, 'users': False},
}
# Test mapping between team users and LDAP groups.
TEST_AUTH_LDAP_TEAM_MAP = {
'Domain Users Team': {
'organization': 'Test Org',
'users': ['CN=Domain Users,CN=Users,DC=example,DC=com'],
'remove': False,
},
'Admins Team': {
'organization': 'Admins Org',
'users': 'CN=Domain Admins,CN=Users,DC=example,DC=com',
'remove': True,
},
'Everyone Team': {
'organization': 'Test Org 2',
'users': True,
},
}
# Expected results from team mapping. After login, should user be a member of
# the given team?
TEST_AUTH_LDAP_TEAM_MAP_RESULT = {
'Domain Users Team': {'users': False},
'Admins Team': {'users': True},
'Everyone Team': {'users': True},
}
# Second test mapping for teams to remove user.
TEST_AUTH_LDAP_TEAM_MAP_2 = {
'Domain Users Team': {
'organization': 'Test Org',
'users': ['CN=Domain Users,CN=Users,DC=example,DC=com'],
'remove': False,
},
'Admins Team': {
'organization': 'Admins Org',
'users': 'CN=Administrators,CN=Builtin,DC=example,DC=com',
'remove': True,
},
'Everyone Team': {
'organization': 'Test Org 2',
'users': False,
'remove': False,
},
}
# Expected results from second team mapping. After login, should user be a
# member of the given team?
TEST_AUTH_LDAP_TEAM_MAP_2_RESULT = {
'Domain Users Team': {'users': False},
'Admins Team': {'users': False},
'Everyone Team': {'users': True},
}
###############################################################################
# RADIUS AUTH SETTINGS
###############################################################################
RADIUS_SERVER = ''
RADIUS_PORT = 1812
RADIUS_SECRET = ''
###############################################################################
# SOCIAL AUTH SETTINGS
###############################################################################
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = ''
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = ''
#SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = ['profile']
#SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS = ['example.com']
#SOCIAL_AUTH_GOOGLE_OAUTH2_AUTH_EXTRA_ARGUMENTS = {'hd': 'example.com'}
SOCIAL_AUTH_GITHUB_KEY = ''
SOCIAL_AUTH_GITHUB_SECRET = ''
SOCIAL_AUTH_GITHUB_ORG_KEY = ''
SOCIAL_AUTH_GITHUB_ORG_SECRET = ''
SOCIAL_AUTH_GITHUB_ORG_NAME = ''
SOCIAL_AUTH_GITHUB_TEAM_KEY = ''
SOCIAL_AUTH_GITHUB_TEAM_SECRET = ''
SOCIAL_AUTH_GITHUB_TEAM_ID = ''
SOCIAL_AUTH_SAML_SP_ENTITY_ID = ''
SOCIAL_AUTH_SAML_SP_PUBLIC_CERT = ''
SOCIAL_AUTH_SAML_SP_PRIVATE_KEY = ''
SOCIAL_AUTH_SAML_ORG_INFO = {
'en-US': {
'name': 'example',
'displayname': 'Example',
'url': 'http://www.example.com',
},
}
SOCIAL_AUTH_SAML_TECHNICAL_CONTACT = {
'givenName': 'Some User',
'emailAddress': 'suser@example.com',
}
SOCIAL_AUTH_SAML_SUPPORT_CONTACT = {
'givenName': 'Some User',
'emailAddress': 'suser@example.com',
}
SOCIAL_AUTH_SAML_ENABLED_IDPS = {
#'myidp': {
# 'entity_id': 'https://idp.example.com',
# 'url': 'https://myidp.example.com/sso',
# 'x509cert': '',
#},
#'onelogin': {
# 'entity_id': 'https://app.onelogin.com/saml/metadata/123456',
# 'url': 'https://example.onelogin.com/trust/saml2/http-post/sso/123456',
# 'x509cert': '',
# 'attr_user_permanent_id': 'name_id',
# 'attr_first_name': 'User.FirstName',
# 'attr_last_name': 'User.LastName',
# 'attr_username': 'User.email',
# 'attr_email': 'User.email',
#},
}
SOCIAL_AUTH_ORGANIZATION_MAP = {
# Add all users to the default organization.
'Default': {
'users': True,
},
#'Test Org': {
# 'admins': ['admin@example.com'],
# 'users': True,
#},
#'Test Org 2': {
# 'admins': ['admin@example.com', re.compile(r'^tower-[^@]+*?@.*$],
# 'users': re.compile(r'^[^@].*?@example\.com$'),
#},
}
#SOCIAL_AUTH_GOOGLE_OAUTH2_ORGANIZATION_MAP = {}
#SOCIAL_AUTH_GITHUB_ORGANIZATION_MAP = {}
#SOCIAL_AUTH_GITHUB_ORG_ORGANIZATION_MAP = {}
#SOCIAL_AUTH_GITHUB_TEAM_ORGANIZATION_MAP = {}
#SOCIAL_AUTH_SAML_ORGANIZATION_MAP = {}
SOCIAL_AUTH_TEAM_MAP = {
#'My Team': {
# 'organization': 'Test Org',
# 'users': ['re.compile(r'^[^@]+?@test\.example\.com$')'],
# 'remove': True,
#},
#'Other Team': {
# 'organization': 'Test Org 2',
# 'users': re.compile(r'^[^@]+?@test2\.example\.com$'),
# 'remove': False,
#},
}
#SOCIAL_AUTH_GOOGLE_OAUTH2_TEAM_MAP = {}
#SOCIAL_AUTH_GITHUB_TEAM_MAP = {}
#SOCIAL_AUTH_GITHUB_ORG_TEAM_MAP = {}
#SOCIAL_AUTH_GITHUB_TEAM_TEAM_MAP = {}
#SOCIAL_AUTH_SAML_TEAM_MAP = {}
# Uncomment the line below (i.e. set SOCIAL_AUTH_USER_FIELDS to an empty list)
# to prevent new user accounts from being created. Only users who have
# previously logged in using social auth or have a user account with a matching
# email address will be able to login.
#SOCIAL_AUTH_USER_FIELDS = []
# It is also possible to add custom functions to the social auth pipeline for
# more advanced organization and team mapping. Use at your own risk.
#def custom_social_auth_pipeline_function(backend, details, user=None, *args, **kwargs):
# print 'custom:', backend, details, user, args, kwargs
#SOCIAL_AUTH_PIPELINE += (
# 'awx.settings.development.custom_social_auth_pipeline_function',
#)
###############################################################################
# INVENTORY IMPORT TEST SETTINGS
###############################################################################