mirror of
https://github.com/ansible/awx.git
synced 2026-01-17 04:31:21 -03:30
Merge branch 'license_module_switch' into devel
* license_module_switch: Hide eula if stub license is used Fix up some issues on feature validation for licenses Remove any references to internal licensing utilities Switch out existing obfuscated license with external module
This commit is contained in:
commit
8e8324983b
@ -279,7 +279,7 @@ class ApiV1ConfigView(APIView):
|
||||
license_info=license_data,
|
||||
version=get_awx_version(),
|
||||
ansible_version=get_ansible_version(),
|
||||
eula=render_to_string("eula.md"),
|
||||
eula=render_to_string("eula.md") if license_data['license_type'] != 'open' else '',
|
||||
analytics_status=pendo_state
|
||||
)
|
||||
|
||||
@ -323,9 +323,9 @@ class ApiV1ConfigView(APIView):
|
||||
extra=dict(actor=request.user.username))
|
||||
return Response({"error": _("Invalid JSON")}, status=status.HTTP_400_BAD_REQUEST)
|
||||
try:
|
||||
from awx.main.task_engine import TaskEnhancer
|
||||
from awx.main.utils.common import get_licenser
|
||||
license_data = json.loads(data_actual)
|
||||
license_data_validated = TaskEnhancer(**license_data).validate_enhancements()
|
||||
license_data_validated = get_licenser(**license_data).validate()
|
||||
except Exception:
|
||||
logger.warning(smart_text(u"Invalid license submitted."),
|
||||
extra=dict(actor=request.user.username))
|
||||
|
||||
@ -8,7 +8,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from rest_framework.exceptions import APIException
|
||||
|
||||
# Tower
|
||||
from awx.main.task_engine import TaskEnhancer
|
||||
from awx.main.utils.common import get_licenser
|
||||
|
||||
__all__ = ['LicenseForbids', 'get_license', 'get_licensed_features',
|
||||
'feature_enabled', 'feature_exists']
|
||||
@ -20,7 +20,7 @@ class LicenseForbids(APIException):
|
||||
|
||||
|
||||
def _get_validated_license_data():
|
||||
return TaskEnhancer().validate_enhancements()
|
||||
return get_licenser().validate()
|
||||
|
||||
|
||||
def get_license(show_key=False):
|
||||
@ -42,7 +42,10 @@ def get_licensed_features():
|
||||
|
||||
def feature_enabled(name):
|
||||
"""Return True if the requested feature is enabled, False otherwise."""
|
||||
return _get_validated_license_data().get('features', {}).get(name, False)
|
||||
validated_license_data = _get_validated_license_data()
|
||||
if validated_license_data['license_type'] == 'open':
|
||||
return True
|
||||
return validated_license_data.get('features', {}).get(name, False)
|
||||
|
||||
|
||||
def feature_exists(name):
|
||||
|
||||
@ -21,8 +21,6 @@ from awx.main.utils import * # noqa
|
||||
from awx.main.models import * # noqa
|
||||
from awx.main.models.unified_jobs import ACTIVE_STATES
|
||||
from awx.main.models.mixins import ResourceMixin
|
||||
from awx.main.task_engine import TaskEnhancer
|
||||
from awx.conf.license import LicenseForbids
|
||||
|
||||
__all__ = ['get_user_queryset', 'check_user_access', 'check_user_access_with_errors',
|
||||
'user_accessible_objects', 'consumer_access',
|
||||
@ -255,7 +253,10 @@ class BaseAccess(object):
|
||||
return True # User has access to both, permission check passed
|
||||
|
||||
def check_license(self, add_host_name=None, feature=None, check_expiration=True):
|
||||
validation_info = TaskEnhancer().validate_enhancements()
|
||||
validation_info = get_licenser().validate()
|
||||
if validation_info['license_type'] == 'open':
|
||||
return
|
||||
|
||||
if ('test' in sys.argv or 'py.test' in sys.argv[0] or 'jenkins' in sys.argv) and not os.environ.get('SKIP_LICENSE_FIXUP_FOR_TEST', ''):
|
||||
validation_info['free_instances'] = 99999999
|
||||
validation_info['time_remaining'] = 99999999
|
||||
|
||||
@ -22,12 +22,12 @@ from django.utils.encoding import smart_text
|
||||
|
||||
# AWX
|
||||
from awx.main.models import * # noqa
|
||||
from awx.main.task_engine import TaskEnhancer
|
||||
from awx.main.utils import (
|
||||
ignore_inventory_computed_fields,
|
||||
check_proot_installed,
|
||||
wrap_args_with_proot,
|
||||
build_proot_temp_dir
|
||||
build_proot_temp_dir,
|
||||
get_licenser
|
||||
)
|
||||
from awx.main.utils.mem_inventory import MemInventory, dict_to_mem_data
|
||||
from awx.main.signals import disable_activity_stream
|
||||
@ -845,10 +845,12 @@ class Command(NoArgsCommand):
|
||||
self._create_update_group_hosts()
|
||||
|
||||
def check_license(self):
|
||||
license_info = TaskEnhancer().validate_enhancements()
|
||||
license_info = get_licenser().validate()
|
||||
if license_info.get('license_key', 'UNLICENSED') == 'UNLICENSED':
|
||||
logger.error(LICENSE_NON_EXISTANT_MESSAGE)
|
||||
raise CommandError('No license found!')
|
||||
elif license_info['license_type'] == 'open':
|
||||
return
|
||||
available_instances = license_info.get('available_instances', 0)
|
||||
free_instances = license_info.get('free_instances', 0)
|
||||
time_remaining = license_info.get('time_remaining', 0)
|
||||
|
||||
@ -47,10 +47,9 @@ from awx.main.constants import CLOUD_PROVIDERS
|
||||
from awx.main.models import * # noqa
|
||||
from awx.main.models.unified_jobs import ACTIVE_STATES
|
||||
from awx.main.queue import CallbackQueueDispatcher
|
||||
from awx.main.task_engine import TaskEnhancer
|
||||
from awx.main.isolated import run, isolated_manager
|
||||
from awx.main.utils import (get_ansible_version, get_ssh_version, decrypt_field, update_scm_url,
|
||||
check_proot_installed, build_proot_temp_dir,
|
||||
check_proot_installed, build_proot_temp_dir, get_licenser,
|
||||
wrap_args_with_proot, get_system_task_capacity, OutputEventFilter,
|
||||
parse_yaml_or_json, ignore_inventory_computed_fields, ignore_inventory_group_removal)
|
||||
from awx.main.utils.reload import restart_local_services, stop_local_services
|
||||
@ -142,8 +141,8 @@ def run_administrative_checks(self):
|
||||
logger.warn("Running administrative checks.")
|
||||
if not settings.TOWER_ADMIN_ALERTS:
|
||||
return
|
||||
validation_info = TaskEnhancer().validate_enhancements()
|
||||
if validation_info.get('instance_count', 0) < 1:
|
||||
validation_info = get_licenser().validate()
|
||||
if validation_info['license_type'] != 'open' and validation_info.get('instance_count', 0) < 1:
|
||||
return
|
||||
used_percentage = float(validation_info.get('current_instances', 0)) / float(validation_info.get('instance_count', 100))
|
||||
tower_admin_emails = User.objects.filter(is_superuser=True).values_list('email', flat=True)
|
||||
|
||||
@ -29,7 +29,6 @@ from django.utils.encoding import force_text
|
||||
|
||||
# AWX
|
||||
from awx.main.models import * # noqa
|
||||
from awx.main.task_engine import TaskEnhancer
|
||||
from awx.main.utils import get_ansible_version
|
||||
from awx.sso.backends import LDAPSettings
|
||||
from awx.main.tests.URI import URI # noqa
|
||||
@ -178,34 +177,6 @@ class BaseTestMixin(MockCommonlySlowTestMixin):
|
||||
rnd_str = '____' + str(random.randint(1, 9999999))
|
||||
return __name__ + '-generated-' + string + rnd_str
|
||||
|
||||
def create_test_license_file(self, instance_count=10000, license_date=int(time.time() + 3600), features={}):
|
||||
settings.LICENSE = TaskEnhancer(
|
||||
company_name='AWX',
|
||||
contact_name='AWX Admin',
|
||||
contact_email='awx@example.com',
|
||||
license_date=license_date,
|
||||
instance_count=instance_count,
|
||||
license_type='enterprise',
|
||||
features=features,
|
||||
).enhance()
|
||||
|
||||
def create_basic_license_file(self, instance_count=100, license_date=int(time.time() + 3600)):
|
||||
settings.LICENSE = TaskEnhancer(
|
||||
company_name='AWX',
|
||||
contact_name='AWX Admin',
|
||||
contact_email='awx@example.com',
|
||||
license_date=license_date,
|
||||
instance_count=instance_count,
|
||||
license_type='basic',
|
||||
).enhance()
|
||||
|
||||
def create_expired_license_file(self, instance_count=1000, grace_period=False):
|
||||
license_date = time.time() - 1
|
||||
if not grace_period:
|
||||
license_date -= 2592000
|
||||
self.create_test_license_file(instance_count, license_date)
|
||||
os.environ['SKIP_LICENSE_FIXUP_FOR_TEST'] = '1'
|
||||
|
||||
def assertElapsedLessThan(self, seconds):
|
||||
elapsed = time.time() - self._start_time
|
||||
self.assertTrue(elapsed < seconds, 'elapsed time of %0.3fs is greater than %0.3fs' % (elapsed, seconds))
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
|
||||
# Python
|
||||
import time
|
||||
import pytest
|
||||
import mock
|
||||
from contextlib import contextmanager
|
||||
@ -97,16 +96,3 @@ def get_ssh_version(mocker):
|
||||
@pytest.fixture
|
||||
def job_template_with_survey_passwords_unit(job_template_with_survey_passwords_factory):
|
||||
return job_template_with_survey_passwords_factory(persisted=False)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def enterprise_license():
|
||||
from awx.main.task_engine import TaskEnhancer
|
||||
return TaskEnhancer(
|
||||
company_name='AWX',
|
||||
contact_name='AWX Admin',
|
||||
contact_email='awx@example.com',
|
||||
license_date=int(time.time() + 3600),
|
||||
instance_count=10000,
|
||||
license_type='enterprise',
|
||||
).enhance()
|
||||
|
||||
@ -29,26 +29,6 @@ def mock_no_license_file(mocker):
|
||||
return None
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_license_cannot_be_removed_via_system_settings(mock_no_license_file, get, put, patch, delete, admin, enterprise_license):
|
||||
url = reverse('api:setting_singleton_detail', kwargs={'category_slug': 'system'})
|
||||
response = get(url, user=admin, expect=200)
|
||||
assert not response.data['LICENSE']
|
||||
Setting.objects.create(key='TOWER_URL_BASE', value='https://towerhost')
|
||||
Setting.objects.create(key='LICENSE', value=enterprise_license)
|
||||
response = get(url, user=admin, expect=200)
|
||||
assert response.data['LICENSE']
|
||||
put(url, user=admin, data=response.data, expect=200)
|
||||
response = get(url, user=admin, expect=200)
|
||||
assert response.data['LICENSE']
|
||||
patch(url, user=admin, data={}, expect=200)
|
||||
response = get(url, user=admin, expect=200)
|
||||
assert response.data['LICENSE']
|
||||
delete(url, user=admin, expect=204)
|
||||
response = get(url, user=admin, expect=200)
|
||||
assert response.data['LICENSE']
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_url_base_defaults_to_request(options, admin):
|
||||
# If TOWER_URL_BASE is not set, default to the Tower request hostname
|
||||
@ -98,10 +78,8 @@ def test_awx_task_env_validity(get, patch, admin, value, expected):
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_ldap_settings(get, put, patch, delete, admin, enterprise_license):
|
||||
def test_ldap_settings(get, put, patch, delete, admin):
|
||||
url = reverse('api:setting_singleton_detail', kwargs={'category_slug': 'ldap'})
|
||||
get(url, user=admin, expect=404)
|
||||
Setting.objects.create(key='LICENSE', value=enterprise_license)
|
||||
get(url, user=admin, expect=200)
|
||||
# The PUT below will fail at the moment because AUTH_LDAP_GROUP_TYPE
|
||||
# defaults to None but cannot be set to None.
|
||||
@ -124,11 +102,8 @@ def test_ldap_settings(get, put, patch, delete, admin, enterprise_license):
|
||||
'AUTH_LDAP_DENY_GROUP',
|
||||
])
|
||||
@pytest.mark.django_db
|
||||
def test_empty_ldap_dn(get, put, patch, delete, admin, enterprise_license,
|
||||
setting):
|
||||
def test_empty_ldap_dn(get, put, patch, delete, admin, setting):
|
||||
url = reverse('api:setting_singleton_detail', kwargs={'category_slug': 'ldap'})
|
||||
Setting.objects.create(key='LICENSE', value=enterprise_license)
|
||||
|
||||
patch(url, user=admin, data={setting: ''}, expect=200)
|
||||
resp = get(url, user=admin, expect=200)
|
||||
assert resp.data[setting] is None
|
||||
@ -139,10 +114,8 @@ def test_empty_ldap_dn(get, put, patch, delete, admin, enterprise_license,
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_radius_settings(get, put, patch, delete, admin, enterprise_license, settings):
|
||||
def test_radius_settings(get, put, patch, delete, admin, settings):
|
||||
url = reverse('api:setting_singleton_detail', kwargs={'category_slug': 'radius'})
|
||||
get(url, user=admin, expect=404)
|
||||
Setting.objects.create(key='LICENSE', value=enterprise_license)
|
||||
response = get(url, user=admin, expect=200)
|
||||
put(url, user=admin, data=response.data, expect=200)
|
||||
# Set secret via the API.
|
||||
@ -173,13 +146,9 @@ def test_radius_settings(get, put, patch, delete, admin, enterprise_license, set
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_ui_settings(get, put, patch, delete, admin, enterprise_license):
|
||||
def test_ui_settings(get, put, patch, delete, admin):
|
||||
url = reverse('api:setting_singleton_detail', kwargs={'category_slug': 'ui'})
|
||||
response = get(url, user=admin, expect=200)
|
||||
assert 'CUSTOM_LOGO' not in response.data
|
||||
assert 'CUSTOM_LOGIN_INFO' not in response.data
|
||||
Setting.objects.create(key='LICENSE', value=enterprise_license)
|
||||
response = get(url, user=admin, expect=200)
|
||||
assert not response.data['CUSTOM_LOGO']
|
||||
assert not response.data['CUSTOM_LOGIN_INFO']
|
||||
put(url, user=admin, data=response.data, expect=200)
|
||||
|
||||
@ -1,106 +1,13 @@
|
||||
# Copyright (c) 2015 Ansible, Inc.
|
||||
# All Rights Reserved.
|
||||
|
||||
import time
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
|
||||
from awx.main.models import Host
|
||||
from awx.main.task_engine import TaskEnhancer
|
||||
from awx.main.utils.common import StubLicense
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_license_writer(inventory, admin):
|
||||
task_enhancer = TaskEnhancer(
|
||||
company_name='acmecorp',
|
||||
contact_name='Michael DeHaan',
|
||||
contact_email='michael@ansibleworks.com',
|
||||
license_date=25000, # seconds since epoch
|
||||
instance_count=500)
|
||||
def test_stub_license():
|
||||
license_actual = StubLicense().validate()
|
||||
assert license_actual['license_key'] == 'OPEN'
|
||||
assert license_actual['valid_key']
|
||||
assert license_actual['compliant']
|
||||
assert license_actual['license_type'] == 'open'
|
||||
|
||||
data = task_enhancer.enhance()
|
||||
|
||||
Host.objects.bulk_create(
|
||||
[
|
||||
Host(
|
||||
name='host.%d' % n,
|
||||
inventory=inventory,
|
||||
created_by=admin,
|
||||
modified=datetime.now(),
|
||||
created=datetime.now())
|
||||
for n in range(12)
|
||||
]
|
||||
)
|
||||
|
||||
assert data['instance_count'] == 500
|
||||
assert data['contact_name'] == 'Michael DeHaan'
|
||||
assert data['contact_email'] == 'michael@ansibleworks.com'
|
||||
assert data['license_date'] == 25000
|
||||
assert data['license_key'] == "11bae31f31c6a6cdcb483a278cdbe98bd8ac5761acd7163a50090b0f098b3a13"
|
||||
|
||||
vdata = task_enhancer.validate_enhancements()
|
||||
|
||||
assert vdata['available_instances'] == 500
|
||||
assert vdata['current_instances'] == 12
|
||||
assert vdata['free_instances'] == 488
|
||||
assert vdata['date_warning'] is True
|
||||
assert vdata['date_expired'] is True
|
||||
assert vdata['license_date'] == 25000
|
||||
assert vdata['time_remaining'] < 0
|
||||
assert vdata['valid_key'] is True
|
||||
assert vdata['compliant'] is False
|
||||
assert vdata['subscription_name']
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_expired_licenses():
|
||||
task_enhancer = TaskEnhancer(
|
||||
company_name='Tower',
|
||||
contact_name='Tower Admin',
|
||||
contact_email='tower@ansible.com',
|
||||
license_date=int(time.time() - 3600),
|
||||
instance_count=100,
|
||||
trial=True)
|
||||
task_enhancer.enhance()
|
||||
vdata = task_enhancer.validate_enhancements()
|
||||
|
||||
assert vdata['compliant'] is False
|
||||
assert vdata['grace_period_remaining'] < 0
|
||||
|
||||
task_enhancer = TaskEnhancer(
|
||||
company_name='Tower',
|
||||
contact_name='Tower Admin',
|
||||
contact_email='tower@ansible.com',
|
||||
license_date=int(time.time() - 2592001),
|
||||
instance_count=100,
|
||||
trial=False)
|
||||
task_enhancer.enhance()
|
||||
vdata = task_enhancer.validate_enhancements()
|
||||
|
||||
assert vdata['compliant'] is False
|
||||
assert vdata['grace_period_remaining'] < 0
|
||||
|
||||
task_enhancer = TaskEnhancer(
|
||||
company_name='Tower',
|
||||
contact_name='Tower Admin',
|
||||
contact_email='tower@ansible.com',
|
||||
license_date=int(time.time() - 3600),
|
||||
instance_count=100,
|
||||
trial=False)
|
||||
task_enhancer.enhance()
|
||||
vdata = task_enhancer.validate_enhancements()
|
||||
|
||||
assert vdata['compliant'] is False
|
||||
assert vdata['grace_period_remaining'] > 0
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_cloudforms_license(mocker):
|
||||
with mocker.patch('awx.main.task_engine.TaskEnhancer._check_cloudforms_subscription', return_value=True):
|
||||
task_enhancer = TaskEnhancer()
|
||||
vdata = task_enhancer.validate_enhancements()
|
||||
assert vdata['compliant'] is True
|
||||
assert vdata['subscription_name'] == "Red Hat CloudForms License"
|
||||
assert vdata['available_instances'] == 9999999
|
||||
assert vdata['license_type'] == 'enterprise'
|
||||
assert vdata['features']['ha'] is True
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
import pytest
|
||||
import mock
|
||||
import os
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.forms.models import model_to_dict
|
||||
from rest_framework.exceptions import ParseError
|
||||
from rest_framework.exceptions import PermissionDenied
|
||||
|
||||
from awx.main.access import (
|
||||
BaseAccess,
|
||||
@ -257,40 +255,6 @@ class TestWorkflowAccessMethods:
|
||||
assert access.can_add({'organization': 1})
|
||||
|
||||
|
||||
class TestCheckLicense:
|
||||
@pytest.fixture
|
||||
def validate_enhancements_mocker(self, mocker):
|
||||
os.environ['SKIP_LICENSE_FIXUP_FOR_TEST'] = '1'
|
||||
|
||||
def fn(available_instances=1, free_instances=0, host_exists=False):
|
||||
|
||||
class MockFilter:
|
||||
def exists(self):
|
||||
return host_exists
|
||||
|
||||
mocker.patch('awx.main.tasks.TaskEnhancer.validate_enhancements', return_value={'free_instances': free_instances, 'available_instances': available_instances, 'date_warning': True})
|
||||
|
||||
mock_filter = MockFilter()
|
||||
mocker.patch('awx.main.models.Host.objects.filter', return_value=mock_filter)
|
||||
|
||||
return fn
|
||||
|
||||
def test_check_license_add_host_duplicate(self, validate_enhancements_mocker, user_unit):
|
||||
validate_enhancements_mocker(available_instances=1, free_instances=0, host_exists=True)
|
||||
|
||||
BaseAccess(None).check_license(add_host_name='blah', check_expiration=False)
|
||||
|
||||
def test_check_license_add_host_new_exceed_licence(self, validate_enhancements_mocker, user_unit, mocker):
|
||||
validate_enhancements_mocker(available_instances=1, free_instances=0, host_exists=False)
|
||||
exception = None
|
||||
|
||||
try:
|
||||
BaseAccess(None).check_license(add_host_name='blah', check_expiration=False)
|
||||
except PermissionDenied as e:
|
||||
exception = e
|
||||
|
||||
assert "License count of 1 instances has been reached." == str(exception)
|
||||
|
||||
|
||||
def test_user_capabilities_method():
|
||||
"""Unit test to verify that the user_capabilities method will defer
|
||||
|
||||
@ -29,10 +29,10 @@ from awx.main.models import (
|
||||
)
|
||||
|
||||
from awx.main import tasks
|
||||
from awx.main.task_engine import TaskEnhancer
|
||||
from awx.main.utils import encrypt_field
|
||||
|
||||
|
||||
|
||||
@contextmanager
|
||||
def apply_patches(_patches):
|
||||
[p.start() for p in _patches]
|
||||
@ -78,27 +78,6 @@ def test_send_notifications_list(mocker):
|
||||
assert mock_job.notifications.add.called_with(*mock_notifications)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("current_instances,call_count", [(91, 2), (89,1)])
|
||||
def test_run_admin_checks_usage(mocker, current_instances, call_count):
|
||||
patches = list()
|
||||
patches.append(mocker.patch('awx.main.tasks.User'))
|
||||
|
||||
mock_te = mocker.Mock(spec=TaskEnhancer)
|
||||
mock_te.validate_enhancements.return_value = {'instance_count': 100, 'current_instances': current_instances, 'date_warning': True}
|
||||
patches.append(mocker.patch('awx.main.tasks.TaskEnhancer', return_value=mock_te))
|
||||
|
||||
mock_sm = mocker.Mock()
|
||||
patches.append(mocker.patch('awx.main.tasks.send_mail', wraps=mock_sm))
|
||||
|
||||
with apply_patches(patches):
|
||||
tasks.run_administrative_checks()
|
||||
assert mock_sm.called
|
||||
if call_count == 2:
|
||||
assert '90%' in mock_sm.call_args_list[0][0][0]
|
||||
else:
|
||||
assert 'expire' in mock_sm.call_args_list[0][0][0]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("key,value", [
|
||||
('REST_API_TOKEN', 'SECRET'),
|
||||
('SECRET_KEY', 'SECRET'),
|
||||
|
||||
@ -34,7 +34,7 @@ from django.apps import apps
|
||||
logger = logging.getLogger('awx.main.utils')
|
||||
|
||||
__all__ = ['get_object_or_400', 'get_object_or_403', 'camelcase_to_underscore', 'memoize',
|
||||
'get_ansible_version', 'get_ssh_version', 'get_awx_version', 'update_scm_url',
|
||||
'get_ansible_version', 'get_ssh_version', 'get_licenser', 'get_awx_version', 'update_scm_url',
|
||||
'get_type_for_model', 'get_model_for_type', 'copy_model_by_class',
|
||||
'copy_m2m_relationships' ,'cache_list_capabilities', 'to_python_boolean',
|
||||
'ignore_inventory_computed_fields', 'ignore_inventory_group_removal',
|
||||
@ -162,6 +162,36 @@ def get_awx_version():
|
||||
return __version__
|
||||
|
||||
|
||||
class StubLicense(object):
|
||||
|
||||
features = {
|
||||
'activity_streams': True,
|
||||
'ha': True,
|
||||
'ldap': True,
|
||||
'multiple_organizations': True,
|
||||
'surveys': True,
|
||||
'system_tracking': True,
|
||||
'rebranding': True,
|
||||
'enterprise_auth': True,
|
||||
'workflows': True,
|
||||
}
|
||||
|
||||
def validate(self):
|
||||
return dict(license_key='OPEN',
|
||||
valid_key=True,
|
||||
compliant=True,
|
||||
features=self.features,
|
||||
license_type='open')
|
||||
|
||||
|
||||
def get_licenser(*args, **kwargs):
|
||||
try:
|
||||
from tower_license import TowerLicense
|
||||
return TowerLicense(*args, **kwargs)
|
||||
except ImportError:
|
||||
return StubLicense(*args, **kwargs)
|
||||
|
||||
|
||||
def update_scm_url(scm_type, url, username=True, password=True,
|
||||
check_special_cases=True, scp_format=False):
|
||||
'''
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user