Add a warning bar when the license will become invalid in a week
This commit is contained in:
parent
9aac68fbeb
commit
74c3346562
3 changed files with 26 additions and 3 deletions
|
@ -231,6 +231,7 @@ def render_page_template(name, route_data=None, **kwargs):
|
||||||
preferred_scheme=app.config['PREFERRED_URL_SCHEME'],
|
preferred_scheme=app.config['PREFERRED_URL_SCHEME'],
|
||||||
version_number=version_number,
|
version_number=version_number,
|
||||||
license_insufficient=license_validator.insufficient,
|
license_insufficient=license_validator.insufficient,
|
||||||
|
license_expiring=license_validator.expiring_soon,
|
||||||
**kwargs))
|
**kwargs))
|
||||||
|
|
||||||
resp.headers['X-FRAME-OPTIONS'] = 'DENY'
|
resp.headers['X-FRAME-OPTIONS'] = 'DENY'
|
||||||
|
|
|
@ -240,6 +240,13 @@ mixpanel.init("{{ mixpanel_key }}", { track_pageview : false, debug: {{ is_debug
|
||||||
|
|
||||||
<nav class="navbar navbar-default header-bar co-m-navbar co-fx-box-shadow" role="navigation"></nav>
|
<nav class="navbar navbar-default header-bar co-m-navbar co-fx-box-shadow" role="navigation"></nav>
|
||||||
|
|
||||||
|
{% if not has_billing and license_expiring %}
|
||||||
|
<div class="co-alert co-alert-warning" style="margin-bottom: 0px;">
|
||||||
|
The Quay Enterprise license will expire shortly. Please contact your administrator to avoid
|
||||||
|
service disruption.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if license_insufficient %}
|
{% if license_insufficient %}
|
||||||
<div class="co-alert co-alert-danger" style="margin-bottom: 0px;">
|
<div class="co-alert co-alert-danger" style="margin-bottom: 0px;">
|
||||||
The Quay Enterprise license has expired or is insufficient for this installation. Please contact your administrator.
|
The Quay Enterprise license has expired or is insufficient for this installation. Please contact your administrator.
|
||||||
|
|
|
@ -21,9 +21,12 @@ import jwt
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
TRIAL_GRACE_PERIOD = timedelta(7, 0) # 1 week
|
TRIAL_GRACE_PERIOD = timedelta(days=7) # 1 week
|
||||||
MONTHLY_GRACE_PERIOD = timedelta(335, 0) # 11 months
|
MONTHLY_GRACE_PERIOD = timedelta(days=335) # 11 months
|
||||||
YEARLY_GRACE_PERIOD = timedelta(90, 0) # 3 months
|
YEARLY_GRACE_PERIOD = timedelta(days=90) # 3 months
|
||||||
|
|
||||||
|
LICENSE_SOON_DELTA = timedelta(days=7) # 1 week
|
||||||
|
|
||||||
LICENSE_FILENAME = 'license'
|
LICENSE_FILENAME = 'license'
|
||||||
|
|
||||||
QUAY_ENTITLEMENT = 'software.quay'
|
QUAY_ENTITLEMENT = 'software.quay'
|
||||||
|
@ -338,10 +341,16 @@ class LicenseValidator(Thread):
|
||||||
|
|
||||||
# multiprocessing.Value does not ensure consistent write-after-reads, but we don't need that.
|
# multiprocessing.Value does not ensure consistent write-after-reads, but we don't need that.
|
||||||
self._license_is_insufficient = multiprocessing.Value(c_bool, True)
|
self._license_is_insufficient = multiprocessing.Value(c_bool, True)
|
||||||
|
self._license_expiring_soon = multiprocessing.Value(c_bool, True)
|
||||||
|
|
||||||
super(LicenseValidator, self).__init__(*args, **kwargs)
|
super(LicenseValidator, self).__init__(*args, **kwargs)
|
||||||
self.daemon = True
|
self.daemon = True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def expiring_soon(self):
|
||||||
|
""" Returns whether the license will be expiring soon (a week from now). """
|
||||||
|
return self._license_expiring_soon.value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def insufficient(self):
|
def insufficient(self):
|
||||||
return self._license_is_insufficient.value
|
return self._license_is_insufficient.value
|
||||||
|
@ -354,14 +363,20 @@ class LicenseValidator(Thread):
|
||||||
try:
|
try:
|
||||||
current_license = self._config_provider.get_license()
|
current_license = self._config_provider.get_license()
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
|
soon = now + LICENSE_SOON_DELTA
|
||||||
any_invalid = not all(current_license.validate_entitlement_requirement(req, now).is_met()
|
any_invalid = not all(current_license.validate_entitlement_requirement(req, now).is_met()
|
||||||
for req in self._entitlement_requirements)
|
for req in self._entitlement_requirements)
|
||||||
|
soon_invalid = not all(current_license.validate_entitlement_requirement(req, soon).is_met()
|
||||||
|
for req in self._entitlement_requirements)
|
||||||
logger.debug('updating license license_is_insufficient to %s', any_invalid)
|
logger.debug('updating license license_is_insufficient to %s', any_invalid)
|
||||||
|
logger.debug('updating license license_expiring_soon to %s', soon_invalid)
|
||||||
except (IOError, LicenseDecodeError):
|
except (IOError, LicenseDecodeError):
|
||||||
logger.exception('failed to validate license')
|
logger.exception('failed to validate license')
|
||||||
any_invalid = True
|
any_invalid = True
|
||||||
|
soon_invalid = False
|
||||||
|
|
||||||
self._license_is_insufficient.value = any_invalid
|
self._license_is_insufficient.value = any_invalid
|
||||||
|
self._license_expiring_soon.value = soon_invalid
|
||||||
return any_invalid
|
return any_invalid
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
|
Reference in a new issue