Openstack dashboard添加license控制功能
openstack_dashboard/settings.py中MIDDLEWARE_CLASSES添加中间件horizon.middleware.LicenseMiddleware。
horizon/middleware/目录中添加license.py,用于检测license状态的中间件,将license状态写入session中。
class LicenseMiddleware(object):
def process_request(self, request):
response = check_license()
request.session['license_info'] = response
return
horizon/middleware/init.py中添加license中间件
from horizon.middleware import license
LicenseMiddleware = license.LicenseMiddleware
修改table_actions和row_actions的基类horizon.tables.actions.BaseAction
添加判断license的方法,对license不敏感的直接返回True。
def _check_license(self, request):
expire_sensitive_object = ['CreateVolume', 'DeleteVolume', 'StartInstance', 'LaunchLinkNG', 'DeleteInstance',
'LaunchImage', 'LaunchImageNG', 'CreateImage', 'CreateVolumeFromImage',
'ImportKeyPair', 'CreateKeyPair', 'CreateNetwork', 'CreateSubnet', 'CreateRouter',
'CreateGroup', 'CreateRule', 'AllocateIP', 'CreateAggregateAction',
'ManageVolumeAction', 'CreateVolumeType', 'CreateQosSpec', 'CreateFlavor',
'AdminCreateImage', 'AdminAllocateFloatingIP', 'UpdateDefaultQuotas',
'CreateProject', 'CreateUserLink', 'ModifyQuotas']
if self.__class__.__name__ in expire_sensitive_object:
self.has_valid_license = request.session.get('license_info')
else:
self.has_valid_license = True
在horizon.tables.actions.BaseAction
的_allowed
中添加_check_license
的调用
def _allowed(self, request, datum):
self._check_license(request)
policy_check = utils_settings.import_setting("POLICY_CHECK_FUNCTION")
if policy_check and self.policy_rules:
target = self.get_policy_target(request, datum)
return (policy_check(self.policy_rules, request, target) and
self.allowed(request, datum))
return self.allowed(request, datum)
在模板horizon/templates/horizon/common/_data_table_action.html
添加license的控制
{% load horizon %}
{% load i18n %}
{% minifyspace %}
{% if action.method != "GET" %}
<button {{ action.attr_string_nc|safe }}
{% if not action.has_valid_license %} disabled="disabled" {% endif %}
class="data-table-action
{% if is_small %}btn-sm{% endif %}
{% for class in action.get_default_classes %}
{{ class }}
{% endfor %}
{% if action.action_type %}
btn-{{ action.action_type }}
{% endif %} btn"
name="action"
{% if action.help_text %}
help_text="{{ action.help_text }}"
{% endif %}
type="submit"
{% if is_table_action %}
value="{{ action.get_param_name }}">
{% if action.icon != None %}
<span class="fa fa-{{ action.icon }}"></span>
{% endif %}
{% if action.handles_multiple %}
{% if not action.has_valid_license %}
{{ action.verbose_name_plural }} ({% trans "License Expired" %})
{% else %}
{{ action.verbose_name_plural }}
{% endif %}
{% else %}
{% if not action.has_valid_license %}
{{ action.verbose_name }} ({% trans "License Expired" %})
{% else %}
{{ action.verbose_name }}
{% endif %}
{% endif %}
{% else %}
value="{{ action.table.name }}__{{ action.name }}__{{ row_id }}">
{% if action.has_valid_license %}
{{ action.verbose_name }}
{% else %}
{{ action.verbose_name }} ({% trans "License Expired" %})
{% endif %}
{% endif %}
</button>
{% else %}
<a {{ action.attr_string_nc|safe }}
class="btn data-table-action {% if is_single %}btn-default {% endif %}{% if is_small %}btn-sm {% endif %}{{ action.get_final_css|safe }}"
{% if is_table_action %}
{% if action.has_valid_license %}
href="{{ action.get_link_url }}"
{% else %}
href="#"
onclick="return false;"
disabled="true"
style="color:#ccc;"
{% endif %}
title="{{ action.verbose_name }}">
{% if action.icon != None %}
<span class="fa fa-{{ action.icon }}"></span>
{% endif %}
{% else %}
{% if action.has_valid_license %}
href="{{ action.bound_url }}"
{% else %}
href="#"
onclick="return false;"
disabled="true"
style="color:#ccc;"
{% endif %}>
{% endif %}
{% if action.has_valid_license %}
{{ action.verbose_name }}
{% else %}
{{ action.verbose_name }} ({% trans "License Expired" %})
{% endif %}
</a>
{% endif %}
{% endminifyspace %}
为了防止修改html元素进行使用,可以在api侧进行控制。
添加装饰器
def has_valid_license(func):
def wrapper(*args, **kwargs):
request = args[0]
license_info = request.session.get('license_info')
if license_info:
return func(*args, **kwargs)
else:
class LicenseExpiredError(Exception):
pass
raise LicenseExpiredError(_('License Expired'))
return wrapper
在openstack_dashboard.api.xxx
xxx
对openstack组件名,在需要license控制的方法前添加@has_valid_license
装饰器即可。