132 lines
3.9 KiB
Python
132 lines
3.9 KiB
Python
# 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 oslo_log import log as logging
|
|
|
|
from bilean.common import exception
|
|
from bilean.common.i18n import _
|
|
from bilean.common.i18n import _LE
|
|
from bilean.common import schema
|
|
from bilean.db import api as db_api
|
|
from bilean.drivers import base as driver_base
|
|
from bilean.plugins import base
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class ServerRule(base.Rule):
|
|
'''Rule for an OpenStack Nova server.'''
|
|
|
|
KEYS = (
|
|
PRICE_MAPPING, UNIT,
|
|
) = (
|
|
'price_mapping', 'unit',
|
|
)
|
|
|
|
PM_KEYS = (
|
|
FLAVOR, PRICE,
|
|
) = (
|
|
'flavor', 'price',
|
|
)
|
|
|
|
AVAILABLE_UNIT = (
|
|
PER_HOUR, PER_SEC,
|
|
) = (
|
|
'per_hour', 'per_sec',
|
|
)
|
|
|
|
properties_schema = {
|
|
PRICE_MAPPING: schema.List(
|
|
_('A list specifying the price of each flavor'),
|
|
schema=schema.Map(
|
|
_('A map specifying the pricce of a flavor.'),
|
|
schema={
|
|
FLAVOR: schema.String(
|
|
_('Flavor id to set price.'),
|
|
),
|
|
PRICE: schema.Integer(
|
|
_('Price of this flavor.'),
|
|
),
|
|
}
|
|
),
|
|
required=True,
|
|
updatable=True,
|
|
),
|
|
UNIT: schema.String(
|
|
_('Unit of price, per_hour or per_sec.'),
|
|
default='per_hour',
|
|
),
|
|
}
|
|
|
|
def get_price(self, resource):
|
|
'''Get the price of resource in seconds.
|
|
|
|
If no exact price found, it shows that rule of the server's flavor
|
|
has not been set, will return 0 as the price notify admin to set
|
|
it.
|
|
|
|
:param: resource: Resource object to find price.
|
|
'''
|
|
flavor = resource.properties.get('flavor')
|
|
if not flavor:
|
|
raise exception.Error(msg='Flavor should be provided to get '
|
|
'the price of server.')
|
|
p_mapping = self.properties.get(self.PRICE_MAPPING)
|
|
price = 0
|
|
for pm in p_mapping:
|
|
if flavor == pm.get(self.FLAVOR):
|
|
price = pm.get(self.PRICE)
|
|
if self.PER_HOUR == self.properties.get(self.UNIT) and price > 0:
|
|
price = price * 1.0 / 3600
|
|
return price
|
|
|
|
|
|
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, context, ignore_missing=True, timeout=None):
|
|
'''Delete resource from other services.'''
|
|
|
|
# Delete resource from db
|
|
db_api.resource_delete(context, self.id)
|
|
|
|
# Delete resource from nova
|
|
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
|
|
|
|
|
|
class ServerPlugin(base.Plugin):
|
|
'''Plugin for Openstack Nova server.'''
|
|
|
|
RuleClass = ServerRule
|
|
ResourceClass = ServerResource
|
|
notification_exchanges = ['nova']
|