Release instance when freeze user
Change-Id: I54694f0573615399dad55fdbc4b82bfa51b4e0ca
This commit is contained in:
parent
f980eeb988
commit
df6044d409
|
@ -47,6 +47,15 @@ service_opts = [
|
||||||
help=_('The directory to search for environment files.')),
|
help=_('The directory to search for environment files.')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
engine_opts = [
|
||||||
|
cfg.StrOpt('environment_dir',
|
||||||
|
default='/etc/bilean/environments',
|
||||||
|
help=_('The directory to search for environment files.')),
|
||||||
|
cfg.IntOpt('default_action_timeout',
|
||||||
|
default=3600,
|
||||||
|
help=_('Timeout in seconds for actions.')),
|
||||||
|
]
|
||||||
|
|
||||||
rpc_opts = [
|
rpc_opts = [
|
||||||
cfg.StrOpt('host',
|
cfg.StrOpt('host',
|
||||||
default=socket.gethostname(),
|
default=socket.gethostname(),
|
||||||
|
@ -91,6 +100,7 @@ revision_opts = [
|
||||||
|
|
||||||
def list_opts():
|
def list_opts():
|
||||||
yield None, rpc_opts
|
yield None, rpc_opts
|
||||||
|
yield None, engine_opts
|
||||||
yield None, service_opts
|
yield None, service_opts
|
||||||
yield None, cloud_backend_opts
|
yield None, cloud_backend_opts
|
||||||
yield paste_deploy_group.name, paste_deploy_opts
|
yield paste_deploy_group.name, paste_deploy_opts
|
||||||
|
|
|
@ -39,7 +39,7 @@ def global_env():
|
||||||
|
|
||||||
|
|
||||||
class Environment(object):
|
class Environment(object):
|
||||||
'''An object that contains all rules, policies and customizations.'''
|
'''An object that contains all rules, resources and customizations.'''
|
||||||
|
|
||||||
SECTIONS = (
|
SECTIONS = (
|
||||||
PARAMETERS, CUSTOM_RULES,
|
PARAMETERS, CUSTOM_RULES,
|
||||||
|
@ -57,9 +57,12 @@ class Environment(object):
|
||||||
if is_global:
|
if is_global:
|
||||||
self.rule_registry = registry.Registry('rules')
|
self.rule_registry = registry.Registry('rules')
|
||||||
self.driver_registry = registry.Registry('drivers')
|
self.driver_registry = registry.Registry('drivers')
|
||||||
|
self.resource_registry = registry.Registry('resources')
|
||||||
else:
|
else:
|
||||||
self.rule_registry = registry.Registry(
|
self.rule_registry = registry.Registry(
|
||||||
'rules', global_env().rule_registry)
|
'rules', global_env().rule_registry)
|
||||||
|
self.resource_registry = registry.Registry(
|
||||||
|
'resources', global_env().resource_registry)
|
||||||
self.driver_registry = registry.Registry(
|
self.driver_registry = registry.Registry(
|
||||||
'drivers', global_env().driver_registry)
|
'drivers', global_env().driver_registry)
|
||||||
|
|
||||||
|
@ -118,6 +121,20 @@ class Environment(object):
|
||||||
def get_rule_types(self):
|
def get_rule_types(self):
|
||||||
return self.rule_registry.get_types()
|
return self.rule_registry.get_types()
|
||||||
|
|
||||||
|
def register_resource(self, name, plugin):
|
||||||
|
self._check_plugin_name('Resource', name)
|
||||||
|
self.resource_registry.register_plugin(name, plugin)
|
||||||
|
|
||||||
|
def get_resource(self, name):
|
||||||
|
self._check_plugin_name('Resource', name)
|
||||||
|
plugin = self.resource_registry.get_plugin(name)
|
||||||
|
if plugin is None:
|
||||||
|
raise exception.ResourceTypeNotFound(resource_type=name)
|
||||||
|
return plugin
|
||||||
|
|
||||||
|
def get_resource_types(self):
|
||||||
|
return self.resource_registry.get_types()
|
||||||
|
|
||||||
def register_driver(self, name, plugin):
|
def register_driver(self, name, plugin):
|
||||||
self._check_plugin_name('Driver', name)
|
self._check_plugin_name('Driver', name)
|
||||||
self.driver_registry.register_plugin(name, plugin)
|
self.driver_registry.register_plugin(name, plugin)
|
||||||
|
@ -180,12 +197,13 @@ def initialize():
|
||||||
for name, plugin in entries:
|
for name, plugin in entries:
|
||||||
env.register_rule(name, plugin)
|
env.register_rule(name, plugin)
|
||||||
|
|
||||||
try:
|
entries = _get_mapping('bilean.resources')
|
||||||
|
for name, plugin in entries:
|
||||||
|
env.register_resource(name, plugin)
|
||||||
|
|
||||||
entries = _get_mapping('bilean.drivers')
|
entries = _get_mapping('bilean.drivers')
|
||||||
for name, plugin in entries:
|
for name, plugin in entries:
|
||||||
env.register_driver(name, plugin)
|
env.register_driver(name, plugin)
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
env.read_global_environment()
|
env.read_global_environment()
|
||||||
_environment = env
|
_environment = env
|
||||||
|
|
|
@ -17,7 +17,7 @@ from bilean.common import exception
|
||||||
from bilean.common.i18n import _
|
from bilean.common.i18n import _
|
||||||
from bilean.common import utils
|
from bilean.common import utils
|
||||||
from bilean.db import api as db_api
|
from bilean.db import api as db_api
|
||||||
from bilean.engine import resource as resource_mod
|
from bilean.resources import base as resource_base
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
|
@ -123,7 +123,7 @@ def record(context, user_id, action=None, seconds=0, value=0):
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if action == 'charge':
|
if action == 'charge':
|
||||||
resources = resource_mod.Resource.load_all(
|
resources = resource_base.Resource.load_all(
|
||||||
context, user_id=user_id, project_safe=False)
|
context, user_id=user_id, project_safe=False)
|
||||||
for resource in resources:
|
for resource in resources:
|
||||||
usage = resource.rate * seconds
|
usage = resource.rate * seconds
|
||||||
|
|
|
@ -74,16 +74,15 @@ class BileanScheduler(object):
|
||||||
self._scheduler = BackgroundScheduler()
|
self._scheduler = BackgroundScheduler()
|
||||||
self.notifier = notifier.Notifier()
|
self.notifier = notifier.Notifier()
|
||||||
self.engine_id = kwargs.get('engine_id', None)
|
self.engine_id = kwargs.get('engine_id', None)
|
||||||
self.context = kwargs.get('context', None)
|
|
||||||
if not self.context:
|
|
||||||
self.context = bilean_context.get_admin_context()
|
|
||||||
if cfg.CONF.scheduler.store_ap_job:
|
if cfg.CONF.scheduler.store_ap_job:
|
||||||
self._scheduler.add_jobstore(cfg.CONF.scheduler.backend,
|
self._scheduler.add_jobstore(cfg.CONF.scheduler.backend,
|
||||||
url=cfg.CONF.scheduler.connection)
|
url=cfg.CONF.scheduler.connection)
|
||||||
|
|
||||||
def init_scheduler(self):
|
def init_scheduler(self):
|
||||||
"""Init all jobs related to the engine from db."""
|
"""Init all jobs related to the engine from db."""
|
||||||
jobs = db_api.job_get_all(self.context, engine_id=self.engine_id) or []
|
admin_context = bilean_context.get_admin_context()
|
||||||
|
jobs = [] or db_api.job_get_all(admin_context,
|
||||||
|
engine_id=self.engine_id)
|
||||||
for job in jobs:
|
for job in jobs:
|
||||||
if self.is_exist(job.id):
|
if self.is_exist(job.id):
|
||||||
continue
|
continue
|
||||||
|
@ -96,7 +95,7 @@ class BileanScheduler(object):
|
||||||
params=job.parameters)
|
params=job.parameters)
|
||||||
|
|
||||||
# Init daily job for all users
|
# Init daily job for all users
|
||||||
users = user_mod.User.load_all(self.context)
|
users = user_mod.User.load_all(admin_context)
|
||||||
for user in users:
|
for user in users:
|
||||||
job_id = self._generate_job_id(user.id, self.DAILY)
|
job_id = self._generate_job_id(user.id, self.DAILY)
|
||||||
if self.is_exist(job_id):
|
if self.is_exist(job_id):
|
||||||
|
@ -176,38 +175,41 @@ class BileanScheduler(object):
|
||||||
return job is not None
|
return job is not None
|
||||||
|
|
||||||
def _notify_task(self, user_id):
|
def _notify_task(self, user_id):
|
||||||
user = user_mod.User.load(self.context, user_id=user_id)
|
admin_context = bilean_context.get_admin_context()
|
||||||
|
user = user_mod.User.load(admin_context, user_id=user_id)
|
||||||
reason = "The balance is almost use up"
|
reason = "The balance is almost use up"
|
||||||
msg = {'user': user.id, 'notification': reason}
|
msg = {'user': user.id, 'notification': reason}
|
||||||
self.notifier.info('billing.notify', msg)
|
self.notifier.info('billing.notify', msg)
|
||||||
if user.status != user.FREEZE and user.rate > 0:
|
if user.status != user.FREEZE and user.rate > 0:
|
||||||
user.do_bill(self.context)
|
user.do_bill(admin_context)
|
||||||
try:
|
try:
|
||||||
db_api.job_delete(
|
db_api.job_delete(
|
||||||
self.context, self._generate_job_id(user.id, 'notify'))
|
admin_context, self._generate_job_id(user.id, 'notify'))
|
||||||
except exception.NotFound as e:
|
except exception.NotFound as e:
|
||||||
LOG.warn(_("Failed in deleting job: %s") % six.text_type(e))
|
LOG.warn(_("Failed in deleting job: %s") % six.text_type(e))
|
||||||
user.set_status(self.context, user.WARNING, reason)
|
user.set_status(admin_context, user.WARNING, reason)
|
||||||
self.update_user_job(user)
|
self.update_user_job(user)
|
||||||
|
|
||||||
def _daily_task(self, user_id):
|
def _daily_task(self, user_id):
|
||||||
user = user_mod.User.load(self.context, user_id=user_id)
|
admin_context = bilean_context.get_admin_context()
|
||||||
|
user = user_mod.User.load(admin_context, user_id=user_id)
|
||||||
if user.status != user.FREEZE and user.rate > 0:
|
if user.status != user.FREEZE and user.rate > 0:
|
||||||
user.do_bill(self.context)
|
user.do_bill(admin_context)
|
||||||
try:
|
try:
|
||||||
db_api.job_delete(
|
db_api.job_delete(
|
||||||
self.context, self._generate_job_id(user.id, 'daily'))
|
admin_context, self._generate_job_id(user.id, 'daily'))
|
||||||
except exception.NotFound as e:
|
except exception.NotFound as e:
|
||||||
LOG.warn(_("Failed in deleting job: %s") % six.text_type(e))
|
LOG.warn(_("Failed in deleting job: %s") % six.text_type(e))
|
||||||
self.update_user_job(user)
|
self.update_user_job(user)
|
||||||
|
|
||||||
def _freeze_task(self, user_id):
|
def _freeze_task(self, user_id):
|
||||||
user = user_mod.User.load(self.context, user_id=user_id)
|
admin_context = bilean_context.get_admin_context()
|
||||||
|
user = user_mod.User.load(admin_context, user_id=user_id)
|
||||||
if user.status != user.FREEZE and user.rate > 0:
|
if user.status != user.FREEZE and user.rate > 0:
|
||||||
user.do_bill(self.context)
|
user.do_bill(admin_context)
|
||||||
try:
|
try:
|
||||||
db_api.job_delete(
|
db_api.job_delete(
|
||||||
self.context, self._generate_job_id(user.id, 'freeze'))
|
admin_context, self._generate_job_id(user.id, 'freeze'))
|
||||||
except exception.NotFound as e:
|
except exception.NotFound as e:
|
||||||
LOG.warn(_("Failed in deleting job: %s") % six.text_type(e))
|
LOG.warn(_("Failed in deleting job: %s") % six.text_type(e))
|
||||||
self.update_user_job(user)
|
self.update_user_job(user)
|
||||||
|
@ -228,7 +230,8 @@ class BileanScheduler(object):
|
||||||
'job_type': self.NOTIFY,
|
'job_type': self.NOTIFY,
|
||||||
'engine_id': self.engine_id,
|
'engine_id': self.engine_id,
|
||||||
'parameters': {'run_date': utils.format_time(run_date)}}
|
'parameters': {'run_date': utils.format_time(run_date)}}
|
||||||
db_api.job_create(self.context, job)
|
admin_context = bilean_context.get_admin_context()
|
||||||
|
db_api.job_create(admin_context, job)
|
||||||
|
|
||||||
def _add_freeze_job(self, user):
|
def _add_freeze_job(self, user):
|
||||||
if not user.rate:
|
if not user.rate:
|
||||||
|
@ -243,7 +246,8 @@ class BileanScheduler(object):
|
||||||
'job_type': self.FREEZE,
|
'job_type': self.FREEZE,
|
||||||
'engine_id': self.engine_id,
|
'engine_id': self.engine_id,
|
||||||
'parameters': {'run_date': utils.format_time(run_date)}}
|
'parameters': {'run_date': utils.format_time(run_date)}}
|
||||||
db_api.job_create(self.context, job)
|
admin_context = bilean_context.get_admin_context()
|
||||||
|
db_api.job_create(admin_context, job)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _add_daily_job(self, user):
|
def _add_daily_job(self, user):
|
||||||
|
@ -257,18 +261,20 @@ class BileanScheduler(object):
|
||||||
'job_type': self.DAILY,
|
'job_type': self.DAILY,
|
||||||
'engine_id': self.engine_id,
|
'engine_id': self.engine_id,
|
||||||
'parameters': job_params}
|
'parameters': job_params}
|
||||||
db_api.job_create(self.context, job)
|
admin_context = bilean_context.get_admin_context()
|
||||||
|
db_api.job_create(admin_context, job)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update_user_job(self, user):
|
def update_user_job(self, user):
|
||||||
"""Update user's billing job"""
|
"""Update user's billing job"""
|
||||||
# Delete all jobs except daily job
|
# Delete all jobs except daily job
|
||||||
|
admin_context = bilean_context.get_admin_context()
|
||||||
for job_type in self.NOTIFY, self.FREEZE:
|
for job_type in self.NOTIFY, self.FREEZE:
|
||||||
job_id = self._generate_job_id(user.id, job_type)
|
job_id = self._generate_job_id(user.id, job_type)
|
||||||
try:
|
try:
|
||||||
if self.is_exist(job_id):
|
if self.is_exist(job_id):
|
||||||
self.remove_job(job_id)
|
self.remove_job(job_id)
|
||||||
db_api.job_delete(self.context, job_id)
|
db_api.job_delete(admin_context, job_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.warn(_("Failed in deleting job: %s") % six.text_type(e))
|
LOG.warn(_("Failed in deleting job: %s") % six.text_type(e))
|
||||||
|
|
||||||
|
@ -279,12 +285,13 @@ class BileanScheduler(object):
|
||||||
|
|
||||||
def delete_user_jobs(self, user):
|
def delete_user_jobs(self, user):
|
||||||
"""Delete all jobs related the specific user."""
|
"""Delete all jobs related the specific user."""
|
||||||
|
admin_context = bilean_context.get_admin_context()
|
||||||
for job_type in self.job_types:
|
for job_type in self.job_types:
|
||||||
job_id = self._generate_job_id(user.id, job_type)
|
job_id = self._generate_job_id(user.id, job_type)
|
||||||
try:
|
try:
|
||||||
if self.is_exist(job_id):
|
if self.is_exist(job_id):
|
||||||
self.remove_job(job_id)
|
self.remove_job(job_id)
|
||||||
db_api.job_delete(self.context, job_id)
|
db_api.job_delete(admin_context, job_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.warn(_("Failed in deleting job: %s") % six.text_type(e))
|
LOG.warn(_("Failed in deleting job: %s") % six.text_type(e))
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@ from bilean.common import utils
|
||||||
from bilean.engine import environment
|
from bilean.engine import environment
|
||||||
from bilean.engine import event as event_mod
|
from bilean.engine import event as event_mod
|
||||||
from bilean.engine import policy as policy_mod
|
from bilean.engine import policy as policy_mod
|
||||||
from bilean.engine import resource as resource_mod
|
|
||||||
from bilean.engine import scheduler
|
from bilean.engine import scheduler
|
||||||
from bilean.engine import user as user_mod
|
from bilean.engine import user as user_mod
|
||||||
|
from bilean.resources import base as resource_base
|
||||||
from bilean.rules import base as rule_base
|
from bilean.rules import base as rule_base
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
@ -74,17 +74,14 @@ class EngineService(service.Service):
|
||||||
self.target = None
|
self.target = None
|
||||||
self._rpc_server = None
|
self._rpc_server = None
|
||||||
|
|
||||||
if context is None:
|
|
||||||
self.context = bilean_context.get_admin_context()
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.engine_id = socket.gethostname()
|
self.engine_id = socket.gethostname()
|
||||||
|
|
||||||
LOG.info(_LI("Initialise bilean users from keystone."))
|
LOG.info(_LI("Initialise bilean users from keystone."))
|
||||||
user_mod.User.init_users(self.context)
|
admin_context = bilean_context.get_admin_context()
|
||||||
|
user_mod.User.init_users(admin_context)
|
||||||
|
|
||||||
self.scheduler = scheduler.BileanScheduler(engine_id=self.engine_id,
|
self.scheduler = scheduler.BileanScheduler(engine_id=self.engine_id)
|
||||||
context=self.context)
|
|
||||||
LOG.info(_LI("Starting billing scheduler for engine: %s"),
|
LOG.info(_LI("Starting billing scheduler for engine: %s"),
|
||||||
self.engine_id)
|
self.engine_id)
|
||||||
self.scheduler.init_scheduler()
|
self.scheduler.init_scheduler()
|
||||||
|
@ -263,7 +260,7 @@ class EngineService(service.Service):
|
||||||
total_rate = 0
|
total_rate = 0
|
||||||
for resource in resources['resources']:
|
for resource in resources['resources']:
|
||||||
rule = policy.find_rule(cnxt, resource['resource_type'])
|
rule = policy.find_rule(cnxt, resource['resource_type'])
|
||||||
res = resource_mod.Resource('FAKE_ID', user.id,
|
res = resource_base.Resource('FAKE_ID', user.id,
|
||||||
resource['resource_type'],
|
resource['resource_type'],
|
||||||
resource['properties'])
|
resource['properties'])
|
||||||
total_rate += rule.get_price(res)
|
total_rate += rule.get_price(res)
|
||||||
|
@ -283,21 +280,22 @@ class EngineService(service.Service):
|
||||||
would be done.
|
would be done.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
resource = resource_mod.Resource(resource_id, user_id, resource_type,
|
resource = resource_base.Resource(resource_id, user_id, resource_type,
|
||||||
properties)
|
properties)
|
||||||
# Find the exact rule of resource
|
# Find the exact rule of resource
|
||||||
user = user_mod.User.load(self.context, user_id=user_id)
|
admin_context = bilean_context.get_admin_context()
|
||||||
|
user = user_mod.User.load(admin_context, user_id=user_id)
|
||||||
user_policy = policy_mod.Policy.load(
|
user_policy = policy_mod.Policy.load(
|
||||||
self.context, policy_id=user.policy_id)
|
admin_context, policy_id=user.policy_id)
|
||||||
rule = user_policy.find_rule(self.context, resource_type)
|
rule = user_policy.find_rule(admin_context, resource_type)
|
||||||
|
|
||||||
# Update resource with rule_id and rate
|
# Update resource with rule_id and rate
|
||||||
resource.rule_id = rule.id
|
resource.rule_id = rule.id
|
||||||
resource.rate = rule.get_price(resource)
|
resource.rate = rule.get_price(resource)
|
||||||
|
|
||||||
# Update user with resource
|
# Update user with resource
|
||||||
user.update_with_resource(self.context, resource)
|
user.update_with_resource(admin_context, resource)
|
||||||
resource.store(self.context)
|
resource.store(admin_context)
|
||||||
|
|
||||||
# As the rate of user has changed, the billing job for the user
|
# As the rate of user has changed, the billing job for the user
|
||||||
# should change too.
|
# should change too.
|
||||||
|
@ -314,7 +312,7 @@ class EngineService(service.Service):
|
||||||
if show_deleted is not None:
|
if show_deleted is not None:
|
||||||
show_deleted = utils.parse_bool_param('show_deleted',
|
show_deleted = utils.parse_bool_param('show_deleted',
|
||||||
show_deleted)
|
show_deleted)
|
||||||
resources = resource_mod.Resource.load_all(cnxt, user_id=user_id,
|
resources = resource_base.Resource.load_all(cnxt, user_id=user_id,
|
||||||
limit=limit, marker=marker,
|
limit=limit, marker=marker,
|
||||||
sort_keys=sort_keys,
|
sort_keys=sort_keys,
|
||||||
sort_dir=sort_dir,
|
sort_dir=sort_dir,
|
||||||
|
@ -325,37 +323,38 @@ class EngineService(service.Service):
|
||||||
|
|
||||||
@request_context
|
@request_context
|
||||||
def resource_get(self, cnxt, resource_id):
|
def resource_get(self, cnxt, resource_id):
|
||||||
resource = resource_mod.Resource.load(cnxt, resource_id=resource_id)
|
resource = resource_base.Resource.load(cnxt, resource_id=resource_id)
|
||||||
return resource.to_dict()
|
return resource.to_dict()
|
||||||
|
|
||||||
def resource_update(self, cnxt, resource):
|
def resource_update(self, cnxt, resource):
|
||||||
"""Do resource update."""
|
"""Do resource update."""
|
||||||
res = resource_mod.Resource.load(
|
admin_context = bilean_context.get_admin_context()
|
||||||
self.context, resource_id=resource['id'])
|
res = resource_base.Resource.load(
|
||||||
|
admin_context, resource_id=resource['id'])
|
||||||
old_rate = res.rate
|
old_rate = res.rate
|
||||||
res.properties = resource['properties']
|
res.properties = resource['properties']
|
||||||
rule = rule_base.Rule.load(self.context, rule_id=res.rule_id)
|
rule = rule_base.Rule.load(admin_context, rule_id=res.rule_id)
|
||||||
res.rate = rule.get_price(res)
|
res.rate = rule.get_price(res)
|
||||||
res.store(self.context)
|
res.store(admin_context)
|
||||||
res.d_rate = res.rate - old_rate
|
res.d_rate = res.rate - old_rate
|
||||||
|
|
||||||
user = user_mod.User.load(self.context, res.user_id)
|
user = user_mod.User.load(admin_context, res.user_id)
|
||||||
user.update_with_resource(self.context, res, action='update')
|
user.update_with_resource(admin_context, res, action='update')
|
||||||
|
|
||||||
self.scheduler.update_user_job(user)
|
self.scheduler.update_user_job(user)
|
||||||
|
|
||||||
def resource_delete(self, cnxt, resource_id):
|
def resource_delete(self, cnxt, resource_id):
|
||||||
"""Do resource delete"""
|
"""Do resource delete"""
|
||||||
res = resource_mod.Resource.load(
|
admin_context = bilean_context.get_admin_context()
|
||||||
self.context, resource_id=resource_id, project_safe=False)
|
res = resource_base.Resource.load(
|
||||||
user = user_mod.User.load(self.context, user_id=res.user_id)
|
admin_context, resource_id=resource_id, project_safe=False)
|
||||||
user.update_with_resource(self.context, res, action='delete')
|
|
||||||
|
user = user_mod.User.load(admin_context, user_id=res.user_id)
|
||||||
|
user.update_with_resource(admin_context, res, action='delete')
|
||||||
|
|
||||||
self.scheduler.update_user_job(user)
|
self.scheduler.update_user_job(user)
|
||||||
try:
|
|
||||||
res.do_delete(self.context)
|
res.delete(admin_context)
|
||||||
except Exception as ex:
|
|
||||||
LOG.warn(_("Delete resource error %s"), ex)
|
|
||||||
return
|
|
||||||
|
|
||||||
@request_context
|
@request_context
|
||||||
def event_list(self, cnxt, user_id=None, limit=None, marker=None,
|
def event_list(self, cnxt, user_id=None, limit=None, marker=None,
|
||||||
|
@ -409,7 +408,7 @@ class EngineService(service.Service):
|
||||||
}
|
}
|
||||||
policy = policy_mod.Policy(name, **kwargs)
|
policy = policy_mod.Policy(name, **kwargs)
|
||||||
policy.store(cnxt)
|
policy.store(cnxt)
|
||||||
LOG.info(_LI("Policy is created: %(id)s."), policy.id)
|
LOG.info(_LI("Successfully create policy (%s)."), policy.id)
|
||||||
return policy.to_dict()
|
return policy.to_dict()
|
||||||
|
|
||||||
@request_context
|
@request_context
|
||||||
|
|
|
@ -19,7 +19,7 @@ from bilean.common import utils
|
||||||
from bilean.db import api as db_api
|
from bilean.db import api as db_api
|
||||||
from bilean.drivers import base as driver_base
|
from bilean.drivers import base as driver_base
|
||||||
from bilean.engine import event as event_mod
|
from bilean.engine import event as event_mod
|
||||||
from bilean.engine import resource as resource_mod
|
from bilean.resources import base as resource_base
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
@ -242,19 +242,13 @@ class User(object):
|
||||||
|
|
||||||
def _freeze(self, context, reason=None):
|
def _freeze(self, context, reason=None):
|
||||||
'''Freeze user when balance overdraft.'''
|
'''Freeze user when balance overdraft.'''
|
||||||
LOG.info(_("Freeze user because of: %s") % reason)
|
LOG.info(_("Freeze user %(user_id), reason: %(reason)s"),
|
||||||
self._release_resource(context)
|
{'user_id': self.id, 'reason': reason})
|
||||||
LOG.info(_("Balance of user %s overdraft, change user's "
|
resources = resource_base.Resource.load_all(
|
||||||
"status to 'freeze'") % self.id)
|
context, user_id=self.id, project_safe=False)
|
||||||
self.status = self.FREEZE
|
|
||||||
self.status_reason = reason
|
|
||||||
|
|
||||||
def _release_resource(self, context):
|
|
||||||
'''Do freeze user, delete all resources ralated to user.'''
|
|
||||||
filters = {'user_id': self.id}
|
|
||||||
resources = resource_mod.Resource.load_all(context, filters=filters)
|
|
||||||
for resource in resources:
|
for resource in resources:
|
||||||
resource.do_delete(context)
|
resource.do_delete()
|
||||||
|
self.set_status(context, self.FREEZE, reason)
|
||||||
|
|
||||||
def do_delete(self, context):
|
def do_delete(self, context):
|
||||||
db_api.user_delete(context, self.id)
|
db_api.user_delete(context, self.id)
|
||||||
|
@ -266,7 +260,7 @@ class User(object):
|
||||||
total_seconds = (now - self.last_bill).total_seconds()
|
total_seconds = (now - self.last_bill).total_seconds()
|
||||||
self.balance = self.balance - self.rate * total_seconds
|
self.balance = self.balance - self.rate * total_seconds
|
||||||
self.last_bill = now
|
self.last_bill = now
|
||||||
if self.balance < 0:
|
if self.balance <= 0:
|
||||||
self._freeze(context, reason="Balance overdraft")
|
self._freeze(context, reason="Balance overdraft")
|
||||||
self.store(context)
|
self.store(context)
|
||||||
event_mod.record(context, self.id,
|
event_mod.record(context, self.id,
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
from bilean.common import exception
|
from bilean.common import exception
|
||||||
from bilean.common import utils
|
from bilean.common import utils
|
||||||
from bilean.db import api as db_api
|
from bilean.db import api as db_api
|
||||||
|
from bilean.engine import environment
|
||||||
|
|
||||||
|
|
||||||
class Resource(object):
|
class Resource(object):
|
||||||
|
@ -24,6 +25,15 @@ class Resource(object):
|
||||||
something else.
|
something else.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __new__(cls, id, user_id, res_type, properties, **kwargs):
|
||||||
|
"""Create a new resource of the appropriate class."""
|
||||||
|
if cls != Resource:
|
||||||
|
ResourceClass = cls
|
||||||
|
else:
|
||||||
|
ResourceClass = environment.global_env().get_resource(res_type)
|
||||||
|
|
||||||
|
return super(Resource, cls).__new__(ResourceClass)
|
||||||
|
|
||||||
def __init__(self, id, user_id, resource_type, properties, **kwargs):
|
def __init__(self, id, user_id, resource_type, properties, **kwargs):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
|
@ -61,6 +71,10 @@ class Resource(object):
|
||||||
|
|
||||||
return self.id
|
return self.id
|
||||||
|
|
||||||
|
def delete(self, context):
|
||||||
|
'''Delete resource from db.'''
|
||||||
|
db_api.resource_delete(context, self.id)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _from_db_record(cls, record):
|
def _from_db_record(cls, record):
|
||||||
'''Construct a resource object from database record.
|
'''Construct a resource object from database record.
|
||||||
|
@ -95,7 +109,7 @@ class Resource(object):
|
||||||
def load_all(cls, context, user_id=None, show_deleted=False,
|
def load_all(cls, context, user_id=None, show_deleted=False,
|
||||||
limit=None, marker=None, sort_keys=None, sort_dir=None,
|
limit=None, marker=None, sort_keys=None, sort_dir=None,
|
||||||
filters=None, project_safe=True):
|
filters=None, project_safe=True):
|
||||||
'''Retrieve all users of from database.'''
|
'''Retrieve all users from database.'''
|
||||||
|
|
||||||
records = db_api.resource_get_all(context, user_id=user_id,
|
records = db_api.resource_get_all(context, user_id=user_id,
|
||||||
show_deleted=show_deleted,
|
show_deleted=show_deleted,
|
||||||
|
@ -121,14 +135,17 @@ class Resource(object):
|
||||||
}
|
}
|
||||||
return resource_dict
|
return resource_dict
|
||||||
|
|
||||||
def do_delete(self, context, resource_id):
|
@classmethod
|
||||||
db_api.resource_delete(context, resource_id)
|
def do_check(cls, context, user):
|
||||||
|
'''Communicate with other services and check user's resources.
|
||||||
|
|
||||||
def resource_delete_by_physical_resource_id(self, context,
|
This would be a period job of user to check if there are any missing
|
||||||
physical_resource_id,
|
actions, and then make correction.
|
||||||
resource_type):
|
'''
|
||||||
db_api.resource_delete_by_physical_resource_id(
|
|
||||||
context, physical_resource_id, resource_type)
|
|
||||||
|
|
||||||
def resource_delete_by_user_id(self, context, user_id):
|
return NotImplemented
|
||||||
db_api.resource_delete(context, user_id)
|
|
||||||
|
def do_delete(self, ignore_missing=True, timeout=None):
|
||||||
|
'''Delete resource from other services.'''
|
||||||
|
|
||||||
|
return NotImplemented
|
|
@ -0,0 +1,49 @@
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from bilean.common.i18n import _LE
|
||||||
|
from bilean.drivers import base as driver_base
|
||||||
|
from bilean.resources import base
|
||||||
|
|
||||||
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ServerResource(base.Resource):
|
||||||
|
'''Resource for an OpenStack Nova server.'''
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def do_check(context, user):
|
||||||
|
'''Communicate with other services and check user's resources.
|
||||||
|
|
||||||
|
This would be a period job of user to check if there are any missing
|
||||||
|
actions, and then make correction.
|
||||||
|
'''
|
||||||
|
# TODO(ldb)
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
def do_delete(self, ignore_missing=True, timeout=None):
|
||||||
|
'''Delete resource from other services.'''
|
||||||
|
|
||||||
|
novaclient = driver_base.BileanDriver().compute()
|
||||||
|
try:
|
||||||
|
novaclient.server_delete(self.id, ignore_missing=ignore_missing)
|
||||||
|
novaclient.wait_for_server_delete(self.id, timeout=timeout)
|
||||||
|
except Exception as ex:
|
||||||
|
LOG.error(_LE('Error: %s'), six.text_type(ex))
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
|
@ -41,6 +41,9 @@ bilean.drivers =
|
||||||
bilean.rules =
|
bilean.rules =
|
||||||
os.nova.server = bilean.rules.os.nova.server:ServerRule
|
os.nova.server = bilean.rules.os.nova.server:ServerRule
|
||||||
|
|
||||||
|
bilean.resources =
|
||||||
|
os.nova.server = bilean.resources.os.nova.server:ServerResource
|
||||||
|
|
||||||
[global]
|
[global]
|
||||||
setup-hooks =
|
setup-hooks =
|
||||||
pbr.hooks.setup_hook
|
pbr.hooks.setup_hook
|
||||||
|
|
Loading…
Reference in New Issue