mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 16:51:11 +03:00
Add support for hiding settings based on whether features are enabled in the license.
This commit is contained in:
parent
06510ce4b9
commit
5b1df83fcc
@ -78,6 +78,9 @@ register(
|
|||||||
# the other settings change, the cached value for this setting will be
|
# the other settings change, the cached value for this setting will be
|
||||||
# cleared to require it to be recomputed.
|
# cleared to require it to be recomputed.
|
||||||
depends_on=['ANSIBLE_COW_SELECTION'],
|
depends_on=['ANSIBLE_COW_SELECTION'],
|
||||||
|
# Optional; licensed feature required to be able to view or modify this
|
||||||
|
# setting.
|
||||||
|
feature_required='rebranding',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
|
@ -14,7 +14,8 @@ from rest_framework.exceptions import APIException
|
|||||||
from awx.main.task_engine import TaskEnhancer
|
from awx.main.task_engine import TaskEnhancer
|
||||||
from awx.main.utils import memoize
|
from awx.main.utils import memoize
|
||||||
|
|
||||||
__all__ = ['LicenseForbids', 'get_license', 'feature_enabled', 'feature_exists']
|
__all__ = ['LicenseForbids', 'get_license', 'get_licensed_features',
|
||||||
|
'feature_enabled', 'feature_exists']
|
||||||
|
|
||||||
|
|
||||||
class LicenseForbids(APIException):
|
class LicenseForbids(APIException):
|
||||||
@ -42,6 +43,15 @@ def get_license(show_key=False):
|
|||||||
return license_data
|
return license_data
|
||||||
|
|
||||||
|
|
||||||
|
def get_licensed_features():
|
||||||
|
"""Return a set of all features enabled by the active license."""
|
||||||
|
features = set()
|
||||||
|
for feature, enabled in _get_validated_license_data().get('features', {}).items():
|
||||||
|
if enabled:
|
||||||
|
features.add(feature)
|
||||||
|
return features
|
||||||
|
|
||||||
|
|
||||||
def feature_enabled(name):
|
def feature_enabled(name):
|
||||||
"""Return True if the requested feature is enabled, False otherwise."""
|
"""Return True if the requested feature is enabled, False otherwise."""
|
||||||
return _get_validated_license_data().get('features', {}).get(name, False)
|
return _get_validated_license_data().get('features', {}).get(name, False)
|
||||||
|
@ -50,7 +50,7 @@ class SettingsRegistry(object):
|
|||||||
def get_dependent_settings(self, setting):
|
def get_dependent_settings(self, setting):
|
||||||
return self._dependent_settings.get(setting, set())
|
return self._dependent_settings.get(setting, set())
|
||||||
|
|
||||||
def get_registered_categories(self):
|
def get_registered_categories(self, features_enabled=None):
|
||||||
categories = {
|
categories = {
|
||||||
'all': _('All'),
|
'all': _('All'),
|
||||||
'changed': _('Changed'),
|
'changed': _('Changed'),
|
||||||
@ -59,6 +59,10 @@ class SettingsRegistry(object):
|
|||||||
category_slug = kwargs.get('category_slug', None)
|
category_slug = kwargs.get('category_slug', None)
|
||||||
if category_slug is None or category_slug in categories:
|
if category_slug is None or category_slug in categories:
|
||||||
continue
|
continue
|
||||||
|
if features_enabled is not None:
|
||||||
|
feature_required = kwargs.get('feature_required', None)
|
||||||
|
if feature_required and feature_required not in features_enabled:
|
||||||
|
continue
|
||||||
if category_slug == 'user':
|
if category_slug == 'user':
|
||||||
categories['user'] = _('User')
|
categories['user'] = _('User')
|
||||||
categories['user-defaults'] = _('User-Defaults')
|
categories['user-defaults'] = _('User-Defaults')
|
||||||
@ -66,7 +70,7 @@ class SettingsRegistry(object):
|
|||||||
categories[category_slug] = kwargs.get('category', None) or category_slug
|
categories[category_slug] = kwargs.get('category', None) or category_slug
|
||||||
return categories
|
return categories
|
||||||
|
|
||||||
def get_registered_settings(self, category_slug=None, read_only=None):
|
def get_registered_settings(self, category_slug=None, read_only=None, features_enabled=None):
|
||||||
setting_names = []
|
setting_names = []
|
||||||
if category_slug == 'user-defaults':
|
if category_slug == 'user-defaults':
|
||||||
category_slug = 'user'
|
category_slug = 'user'
|
||||||
@ -79,6 +83,10 @@ class SettingsRegistry(object):
|
|||||||
# Note: Doesn't catch fields that set read_only via __init__;
|
# Note: Doesn't catch fields that set read_only via __init__;
|
||||||
# read-only field kwargs should always include read_only=True.
|
# read-only field kwargs should always include read_only=True.
|
||||||
continue
|
continue
|
||||||
|
if features_enabled is not None:
|
||||||
|
feature_required = kwargs.get('feature_required', None)
|
||||||
|
if feature_required and feature_required not in features_enabled:
|
||||||
|
continue
|
||||||
setting_names.append(setting)
|
setting_names.append(setting)
|
||||||
return setting_names
|
return setting_names
|
||||||
|
|
||||||
@ -95,6 +103,7 @@ class SettingsRegistry(object):
|
|||||||
category = field_kwargs.pop('category', None)
|
category = field_kwargs.pop('category', None)
|
||||||
depends_on = frozenset(field_kwargs.pop('depends_on', None) or [])
|
depends_on = frozenset(field_kwargs.pop('depends_on', None) or [])
|
||||||
placeholder = field_kwargs.pop('placeholder', empty)
|
placeholder = field_kwargs.pop('placeholder', empty)
|
||||||
|
feature_required = field_kwargs.pop('feature_required', empty)
|
||||||
if getattr(field_kwargs.get('child', None), 'source', None) is not None:
|
if getattr(field_kwargs.get('child', None), 'source', None) is not None:
|
||||||
field_kwargs['child'].source = None
|
field_kwargs['child'].source = None
|
||||||
field_instance = field_class(**field_kwargs)
|
field_instance = field_class(**field_kwargs)
|
||||||
@ -103,6 +112,8 @@ class SettingsRegistry(object):
|
|||||||
field_instance.depends_on = depends_on
|
field_instance.depends_on = depends_on
|
||||||
if placeholder is not empty:
|
if placeholder is not empty:
|
||||||
field_instance.placeholder = placeholder
|
field_instance.placeholder = placeholder
|
||||||
|
if feature_required is not empty:
|
||||||
|
field_instance.feature_required = feature_required
|
||||||
original_field_instance = field_instance
|
original_field_instance = field_instance
|
||||||
if field_class != original_field_class:
|
if field_class != original_field_class:
|
||||||
original_field_instance = original_field_class(**field_kwargs)
|
original_field_instance = original_field_class(**field_kwargs)
|
||||||
|
@ -19,6 +19,7 @@ from rest_framework import status
|
|||||||
# Tower
|
# Tower
|
||||||
from awx.api.generics import * # noqa
|
from awx.api.generics import * # noqa
|
||||||
from awx.main.utils import * # noqa
|
from awx.main.utils import * # noqa
|
||||||
|
from awx.conf.license import get_licensed_features
|
||||||
from awx.conf.models import Setting
|
from awx.conf.models import Setting
|
||||||
from awx.conf.serializers import SettingCategorySerializer, SettingSingletonSerializer
|
from awx.conf.serializers import SettingCategorySerializer, SettingSingletonSerializer
|
||||||
from awx.conf import settings_registry
|
from awx.conf import settings_registry
|
||||||
@ -37,7 +38,7 @@ class SettingCategoryList(ListAPIView):
|
|||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
setting_categories = []
|
setting_categories = []
|
||||||
categories = settings_registry.get_registered_categories()
|
categories = settings_registry.get_registered_categories(features_enabled=get_licensed_features())
|
||||||
if self.request.user.is_superuser or self.request.user.is_system_auditor:
|
if self.request.user.is_superuser or self.request.user.is_system_auditor:
|
||||||
pass # categories = categories
|
pass # categories = categories
|
||||||
elif 'user' in categories:
|
elif 'user' in categories:
|
||||||
@ -60,7 +61,7 @@ class SettingSingletonDetail(RetrieveUpdateDestroyAPIView):
|
|||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
self.category_slug = self.kwargs.get('category_slug', 'all')
|
self.category_slug = self.kwargs.get('category_slug', 'all')
|
||||||
all_category_slugs = settings_registry.get_registered_categories().keys()
|
all_category_slugs = settings_registry.get_registered_categories(features_enabled=get_licensed_features()).keys()
|
||||||
if self.request.user.is_superuser or getattr(self.request.user, 'is_system_auditor', False):
|
if self.request.user.is_superuser or getattr(self.request.user, 'is_system_auditor', False):
|
||||||
category_slugs = all_category_slugs
|
category_slugs = all_category_slugs
|
||||||
else:
|
else:
|
||||||
@ -70,7 +71,7 @@ class SettingSingletonDetail(RetrieveUpdateDestroyAPIView):
|
|||||||
if self.category_slug not in category_slugs:
|
if self.category_slug not in category_slugs:
|
||||||
raise PermissionDenied()
|
raise PermissionDenied()
|
||||||
|
|
||||||
registered_settings = settings_registry.get_registered_settings(category_slug=self.category_slug, read_only=False)
|
registered_settings = settings_registry.get_registered_settings(category_slug=self.category_slug, read_only=False, features_enabled=get_licensed_features())
|
||||||
if self.category_slug == 'user':
|
if self.category_slug == 'user':
|
||||||
return Setting.objects.filter(key__in=registered_settings, user=self.request.user)
|
return Setting.objects.filter(key__in=registered_settings, user=self.request.user)
|
||||||
else:
|
else:
|
||||||
@ -78,7 +79,7 @@ class SettingSingletonDetail(RetrieveUpdateDestroyAPIView):
|
|||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
settings_qs = self.get_queryset()
|
settings_qs = self.get_queryset()
|
||||||
registered_settings = settings_registry.get_registered_settings(category_slug=self.category_slug)
|
registered_settings = settings_registry.get_registered_settings(category_slug=self.category_slug, features_enabled=get_licensed_features())
|
||||||
all_settings = {}
|
all_settings = {}
|
||||||
for setting in settings_qs:
|
for setting in settings_qs:
|
||||||
all_settings[setting.key] = setting.value
|
all_settings[setting.key] = setting.value
|
||||||
|
@ -18,6 +18,7 @@ register(
|
|||||||
help_text=_('Enable capturing activity for the Tower activity stream.'),
|
help_text=_('Enable capturing activity for the Tower activity stream.'),
|
||||||
category=_('System'),
|
category=_('System'),
|
||||||
category_slug='system',
|
category_slug='system',
|
||||||
|
feature_required='activity_streams',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -27,6 +28,7 @@ register(
|
|||||||
help_text=_('Enable capturing activity for the Tower activity stream when running inventory sync.'),
|
help_text=_('Enable capturing activity for the Tower activity stream when running inventory sync.'),
|
||||||
category=_('System'),
|
category=_('System'),
|
||||||
category_slug='system',
|
category_slug='system',
|
||||||
|
feature_required='activity_streams',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
|
@ -182,6 +182,7 @@ register(
|
|||||||
category=_('LDAP'),
|
category=_('LDAP'),
|
||||||
category_slug='ldap',
|
category_slug='ldap',
|
||||||
placeholder='ldaps://ldap.example.com:636',
|
placeholder='ldaps://ldap.example.com:636',
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -198,6 +199,7 @@ register(
|
|||||||
'for other user information.'),
|
'for other user information.'),
|
||||||
category=_('LDAP'),
|
category=_('LDAP'),
|
||||||
category_slug='ldap',
|
category_slug='ldap',
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -209,6 +211,7 @@ register(
|
|||||||
help_text=_('Password used to bind LDAP user account.'),
|
help_text=_('Password used to bind LDAP user account.'),
|
||||||
category=_('LDAP'),
|
category=_('LDAP'),
|
||||||
category_slug='ldap',
|
category_slug='ldap',
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -219,6 +222,7 @@ register(
|
|||||||
help_text=_('Whether to enable TLS when the LDAP connection is not using SSL.'),
|
help_text=_('Whether to enable TLS when the LDAP connection is not using SSL.'),
|
||||||
category=_('LDAP'),
|
category=_('LDAP'),
|
||||||
category_slug='ldap',
|
category_slug='ldap',
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -237,6 +241,7 @@ register(
|
|||||||
placeholder=collections.OrderedDict([
|
placeholder=collections.OrderedDict([
|
||||||
('OPT_REFERRALS', 0),
|
('OPT_REFERRALS', 0),
|
||||||
]),
|
]),
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -257,6 +262,7 @@ register(
|
|||||||
'SCOPE_SUBTREE',
|
'SCOPE_SUBTREE',
|
||||||
'(sAMAccountName=%(user)s)',
|
'(sAMAccountName=%(user)s)',
|
||||||
),
|
),
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -273,6 +279,7 @@ register(
|
|||||||
category=_('LDAP'),
|
category=_('LDAP'),
|
||||||
category_slug='ldap',
|
category_slug='ldap',
|
||||||
placeholder='uid=%(user)s,OU=Users,DC=example,DC=com',
|
placeholder='uid=%(user)s,OU=Users,DC=example,DC=com',
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -292,6 +299,7 @@ register(
|
|||||||
('last_name', 'sn'),
|
('last_name', 'sn'),
|
||||||
('email', 'mail'),
|
('email', 'mail'),
|
||||||
]),
|
]),
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -310,6 +318,7 @@ register(
|
|||||||
'SCOPE_SUBTREE',
|
'SCOPE_SUBTREE',
|
||||||
'(objectClass=group)',
|
'(objectClass=group)',
|
||||||
),
|
),
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -321,6 +330,7 @@ register(
|
|||||||
'http://pythonhosted.org/django-auth-ldap/groups.html#types-of-groups'),
|
'http://pythonhosted.org/django-auth-ldap/groups.html#types-of-groups'),
|
||||||
category=_('LDAP'),
|
category=_('LDAP'),
|
||||||
category_slug='ldap',
|
category_slug='ldap',
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -336,6 +346,7 @@ register(
|
|||||||
category=_('LDAP'),
|
category=_('LDAP'),
|
||||||
category_slug='ldap',
|
category_slug='ldap',
|
||||||
placeholder='CN=Tower Users,OU=Users,DC=example,DC=com',
|
placeholder='CN=Tower Users,OU=Users,DC=example,DC=com',
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -350,6 +361,7 @@ register(
|
|||||||
category=_('LDAP'),
|
category=_('LDAP'),
|
||||||
category_slug='ldap',
|
category_slug='ldap',
|
||||||
placeholder='CN=Disabled Users,OU=Users,DC=example,DC=com',
|
placeholder='CN=Disabled Users,OU=Users,DC=example,DC=com',
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -368,6 +380,7 @@ register(
|
|||||||
placeholder=collections.OrderedDict([
|
placeholder=collections.OrderedDict([
|
||||||
('is_superuser', 'CN=Domain Admins,CN=Users,DC=example,DC=com'),
|
('is_superuser', 'CN=Domain Admins,CN=Users,DC=example,DC=com'),
|
||||||
]),
|
]),
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -416,6 +429,7 @@ register(
|
|||||||
('remove_admins', True),
|
('remove_admins', True),
|
||||||
])),
|
])),
|
||||||
]),
|
]),
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -454,6 +468,7 @@ register(
|
|||||||
('remove', False),
|
('remove', False),
|
||||||
])),
|
])),
|
||||||
]),
|
]),
|
||||||
|
feature_required='ldap',
|
||||||
)
|
)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -471,6 +486,7 @@ register(
|
|||||||
category=_('RADIUS'),
|
category=_('RADIUS'),
|
||||||
category_slug='radius',
|
category_slug='radius',
|
||||||
placeholder='radius.example.com',
|
placeholder='radius.example.com',
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -483,6 +499,7 @@ register(
|
|||||||
help_text=_('Port of RADIUS server.'),
|
help_text=_('Port of RADIUS server.'),
|
||||||
category=_('RADIUS'),
|
category=_('RADIUS'),
|
||||||
category_slug='radius',
|
category_slug='radius',
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -494,6 +511,7 @@ register(
|
|||||||
help_text=_('Shared secret for authenticating to RADIUS server.'),
|
help_text=_('Shared secret for authenticating to RADIUS server.'),
|
||||||
category=_('RADIUS'),
|
category=_('RADIUS'),
|
||||||
category_slug='radius',
|
category_slug='radius',
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -882,6 +900,7 @@ register(
|
|||||||
category=_('SAML'),
|
category=_('SAML'),
|
||||||
category_slug='saml',
|
category_slug='saml',
|
||||||
depends_on=['TOWER_URL_BASE'],
|
depends_on=['TOWER_URL_BASE'],
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -894,6 +913,7 @@ register(
|
|||||||
'metadata file, you can download one from this URL.'),
|
'metadata file, you can download one from this URL.'),
|
||||||
category=_('SAML'),
|
category=_('SAML'),
|
||||||
category_slug='saml',
|
category_slug='saml',
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -907,6 +927,7 @@ register(
|
|||||||
'valid URL; only used as a unique ID).'),
|
'valid URL; only used as a unique ID).'),
|
||||||
category=_('SAML'),
|
category=_('SAML'),
|
||||||
category_slug='saml',
|
category_slug='saml',
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -920,6 +941,7 @@ register(
|
|||||||
'and include the certificate content here.'),
|
'and include the certificate content here.'),
|
||||||
category=_('SAML'),
|
category=_('SAML'),
|
||||||
category_slug='saml',
|
category_slug='saml',
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -933,6 +955,7 @@ register(
|
|||||||
'and include the private key content here.'),
|
'and include the private key content here.'),
|
||||||
category=_('SAML'),
|
category=_('SAML'),
|
||||||
category_slug='saml',
|
category_slug='saml',
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -950,6 +973,7 @@ register(
|
|||||||
('url', 'http://www.example.com'),
|
('url', 'http://www.example.com'),
|
||||||
])),
|
])),
|
||||||
]),
|
]),
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -965,6 +989,7 @@ register(
|
|||||||
('givenName', 'Technical Contact'),
|
('givenName', 'Technical Contact'),
|
||||||
('emailAddress', 'techsup@example.com'),
|
('emailAddress', 'techsup@example.com'),
|
||||||
]),
|
]),
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -980,6 +1005,7 @@ register(
|
|||||||
('givenName', 'Support Contact'),
|
('givenName', 'Support Contact'),
|
||||||
('emailAddress', 'support@example.com'),
|
('emailAddress', 'support@example.com'),
|
||||||
]),
|
]),
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -1017,6 +1043,7 @@ register(
|
|||||||
('attr_email', 'User.email'),
|
('attr_email', 'User.email'),
|
||||||
])),
|
])),
|
||||||
]),
|
]),
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -1029,6 +1056,7 @@ register(
|
|||||||
category=_('SAML'),
|
category=_('SAML'),
|
||||||
category_slug='saml',
|
category_slug='saml',
|
||||||
placeholder=SOCIAL_AUTH_ORGANIZATION_MAP_PLACEHOLDER,
|
placeholder=SOCIAL_AUTH_ORGANIZATION_MAP_PLACEHOLDER,
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
@ -1041,4 +1069,5 @@ register(
|
|||||||
category=_('SAML'),
|
category=_('SAML'),
|
||||||
category_slug='saml',
|
category_slug='saml',
|
||||||
placeholder=SOCIAL_AUTH_TEAM_MAP_PLACEHOLDER,
|
placeholder=SOCIAL_AUTH_TEAM_MAP_PLACEHOLDER,
|
||||||
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user