Remove usage of unix timestamps
This removes usage of unix timestamps in the codebase. They're replaced by datetime objects. This is part of a larger effort aiming at making cloudkitty timezone-aware. Timezone information will be added to the datetime objects in another patch. Change-Id: I7aadc314ceb5e36277bb51f55065ef558f10a7f2 Story: 2005319 Task: 30235
This commit is contained in:
parent
16b6fa5ce8
commit
0c1546d4aa
|
@ -25,7 +25,6 @@ import wsmeext.pecan as wsme_pecan
|
||||||
from cloudkitty.api.v1.datamodels import storage as storage_models
|
from cloudkitty.api.v1.datamodels import storage as storage_models
|
||||||
from cloudkitty.common import policy
|
from cloudkitty.common import policy
|
||||||
from cloudkitty import storage
|
from cloudkitty import storage
|
||||||
from cloudkitty import utils as ck_utils
|
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
@ -62,10 +61,6 @@ class DataFramesController(rest.RestController):
|
||||||
dataframes = []
|
dataframes = []
|
||||||
filters = {scope_key: tenant_id} if tenant_id else None
|
filters = {scope_key: tenant_id} if tenant_id else None
|
||||||
|
|
||||||
if begin:
|
|
||||||
begin = ck_utils.dt2ts(begin)
|
|
||||||
if end:
|
|
||||||
end = ck_utils.dt2ts(end)
|
|
||||||
try:
|
try:
|
||||||
resp = backend.retrieve(
|
resp = backend.retrieve(
|
||||||
begin, end,
|
begin, end,
|
||||||
|
@ -95,8 +90,8 @@ class DataFramesController(rest.RestController):
|
||||||
frame_tenant = desc[scope_key]
|
frame_tenant = desc[scope_key]
|
||||||
resources.append(resource)
|
resources.append(resource)
|
||||||
dataframe = storage_models.DataFrame(
|
dataframe = storage_models.DataFrame(
|
||||||
begin=ck_utils.iso2dt(frame['period']['begin']),
|
begin=frame['period']['begin'],
|
||||||
end=ck_utils.iso2dt(frame['period']['end']),
|
end=frame['period']['end'],
|
||||||
tenant_id=frame_tenant,
|
tenant_id=frame_tenant,
|
||||||
resources=resources)
|
resources=resources)
|
||||||
dataframes.append(dataframe)
|
dataframes.append(dataframe)
|
||||||
|
|
|
@ -78,7 +78,7 @@ class ScopeState(base.BaseResource):
|
||||||
'scope_key': r.scope_key,
|
'scope_key': r.scope_key,
|
||||||
'fetcher': r.fetcher,
|
'fetcher': r.fetcher,
|
||||||
'collector': r.collector,
|
'collector': r.collector,
|
||||||
'state': str(r.state),
|
'state': r.state.isoformat(),
|
||||||
} for r in results]
|
} for r in results]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,19 +222,6 @@ class BaseCollector(object):
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def last_month():
|
|
||||||
month_start = ck_utils.get_month_start()
|
|
||||||
month_end = ck_utils.get_month_end()
|
|
||||||
start_ts = ck_utils.dt2ts(month_start)
|
|
||||||
end_ts = ck_utils.dt2ts(month_end)
|
|
||||||
return start_ts, end_ts
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def current_month():
|
|
||||||
month_start = ck_utils.get_month_start()
|
|
||||||
return ck_utils.dt2ts(month_start)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _res_to_func(cls, resource_name):
|
def _res_to_func(cls, resource_name):
|
||||||
trans_resource = 'get_'
|
trans_resource = 'get_'
|
||||||
|
@ -262,8 +249,18 @@ class BaseCollector(object):
|
||||||
|
|
||||||
Returns a list of items formatted with
|
Returns a list of items formatted with
|
||||||
``CloudKittyFormatTransformer.format_item``.
|
``CloudKittyFormatTransformer.format_item``.
|
||||||
|
|
||||||
|
:param metric_name: Name of the metric to fetch
|
||||||
|
:type metric_name: str
|
||||||
|
:param start: start of the period
|
||||||
|
:type start: datetime.datetime
|
||||||
|
:param end: end of the period
|
||||||
|
:type end: datetime.datetime
|
||||||
|
:param project_id: ID of the scope for which data should be collected
|
||||||
|
:type project_id: str
|
||||||
|
:param q_filter: Optional filters
|
||||||
|
:type q_filter: dict
|
||||||
"""
|
"""
|
||||||
pass
|
|
||||||
|
|
||||||
def retrieve(self, metric_name, start, end,
|
def retrieve(self, metric_name, start, end,
|
||||||
project_id=None, q_filter=None):
|
project_id=None, q_filter=None):
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
|
from datetime import timedelta
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from gnocchiclient import auth as gauth
|
from gnocchiclient import auth as gauth
|
||||||
|
@ -248,8 +249,8 @@ class GnocchiCollector(collector.BaseCollector):
|
||||||
# FIXME(peschk_l): In order not to miss any resource whose metrics may
|
# FIXME(peschk_l): In order not to miss any resource whose metrics may
|
||||||
# contain measures after its destruction, we scan resources over three
|
# contain measures after its destruction, we scan resources over three
|
||||||
# collect periods.
|
# collect periods.
|
||||||
start -= CONF.collect.period
|
start -= timedelta(seconds=CONF.collect.period)
|
||||||
end += CONF.collect.period
|
end += timedelta(seconds=CONF.collect.period)
|
||||||
query_parameters = self._generate_time_filter(start, end)
|
query_parameters = self._generate_time_filter(start, end)
|
||||||
|
|
||||||
if project_id:
|
if project_id:
|
||||||
|
@ -316,8 +317,8 @@ class GnocchiCollector(collector.BaseCollector):
|
||||||
return self._conn.aggregates.fetch(
|
return self._conn.aggregates.fetch(
|
||||||
op,
|
op,
|
||||||
resource_type=resource_type,
|
resource_type=resource_type,
|
||||||
start=ck_utils.ts2dt(start),
|
start=start,
|
||||||
stop=ck_utils.ts2dt(end),
|
stop=end,
|
||||||
groupby=groupby,
|
groupby=groupby,
|
||||||
search=self.extend_filter(*query_parameters))
|
search=self.extend_filter(*query_parameters))
|
||||||
except (gexceptions.MetricNotFound, gexceptions.BadRequest) as e:
|
except (gexceptions.MetricNotFound, gexceptions.BadRequest) as e:
|
||||||
|
@ -388,10 +389,7 @@ class GnocchiCollector(collector.BaseCollector):
|
||||||
LOG.warning(
|
LOG.warning(
|
||||||
'[{}] An error occured during data collection '
|
'[{}] An error occured during data collection '
|
||||||
'between {} and {}: {}'.format(
|
'between {} and {}: {}'.format(
|
||||||
project_id,
|
project_id, start, end, e),
|
||||||
ck_utils.ts2dt(start),
|
|
||||||
ck_utils.ts2dt(end),
|
|
||||||
e),
|
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
data = self.t_cloudkitty.format_item(
|
data = self.t_cloudkitty.format_item(
|
||||||
|
|
|
@ -175,7 +175,7 @@ class MonascaCollector(collector.BaseCollector):
|
||||||
group_by = self.conf[metric_name]['groupby']
|
group_by = self.conf[metric_name]['groupby']
|
||||||
|
|
||||||
# NOTE(lpeschke): One aggregated measure per collect period
|
# NOTE(lpeschke): One aggregated measure per collect period
|
||||||
period = end - start
|
period = int((end - start).total_seconds())
|
||||||
|
|
||||||
extra_args = self.conf[metric_name]['extra_args']
|
extra_args = self.conf[metric_name]['extra_args']
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
|
@ -186,8 +186,8 @@ class MonascaCollector(collector.BaseCollector):
|
||||||
name=metric_name,
|
name=metric_name,
|
||||||
merge_metrics=True,
|
merge_metrics=True,
|
||||||
dimensions=dimensions,
|
dimensions=dimensions,
|
||||||
start_time=ck_utils.ts2dt(start),
|
start_time=start,
|
||||||
end_time=ck_utils.ts2dt(end),
|
end_time=end,
|
||||||
period=period,
|
period=period,
|
||||||
statistics=extra_args['aggregation_method'],
|
statistics=extra_args['aggregation_method'],
|
||||||
group_by=group_by,
|
group_by=group_by,
|
||||||
|
@ -210,8 +210,8 @@ class MonascaCollector(collector.BaseCollector):
|
||||||
metrics = self._conn.metrics.list(
|
metrics = self._conn.metrics.list(
|
||||||
name=metric_name,
|
name=metric_name,
|
||||||
dimensions=dimensions,
|
dimensions=dimensions,
|
||||||
start_time=ck_utils.ts2dt(start),
|
start_time=start,
|
||||||
end_time=ck_utils.ts2dt(end),
|
end_time=end,
|
||||||
)
|
)
|
||||||
|
|
||||||
resource_key = self.conf[metric_name]['extra_args']['resource_key']
|
resource_key = self.conf[metric_name]['extra_args']['resource_key']
|
||||||
|
|
|
@ -139,7 +139,7 @@ class PrometheusCollector(collector.BaseCollector):
|
||||||
method = self.conf[metric_name]['extra_args']['aggregation_method']
|
method = self.conf[metric_name]['extra_args']['aggregation_method']
|
||||||
groupby = self.conf[metric_name].get('groupby', [])
|
groupby = self.conf[metric_name].get('groupby', [])
|
||||||
metadata = self.conf[metric_name].get('metadata', [])
|
metadata = self.conf[metric_name].get('metadata', [])
|
||||||
period = end - start
|
period = int((end - start).total_seconds())
|
||||||
time = end
|
time = end
|
||||||
|
|
||||||
query = '{0}({0}_over_time({1}{{{2}="{3}"}}[{4}s])) by ({5})'.format(
|
query = '{0}({0}_over_time({1}{{{2}="{3}"}}[{4}s])) by ({5})'.format(
|
||||||
|
@ -154,7 +154,7 @@ class PrometheusCollector(collector.BaseCollector):
|
||||||
try:
|
try:
|
||||||
res = self._conn.get_instant(
|
res = self._conn.get_instant(
|
||||||
query,
|
query,
|
||||||
time,
|
time.isoformat(),
|
||||||
)
|
)
|
||||||
except PrometheusResponseError as e:
|
except PrometheusResponseError as e:
|
||||||
raise CollectError(*e.args)
|
raise CollectError(*e.args)
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
|
from datetime import timedelta
|
||||||
import decimal
|
import decimal
|
||||||
|
import functools
|
||||||
import hashlib
|
import hashlib
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import random
|
import random
|
||||||
|
@ -222,6 +224,13 @@ class APIWorker(BaseWorker):
|
||||||
return price
|
return price
|
||||||
|
|
||||||
|
|
||||||
|
def _check_state(obj, period, tenant_id):
|
||||||
|
timestamp = obj._state.get_state(tenant_id)
|
||||||
|
return ck_utils.check_time_state(timestamp,
|
||||||
|
period,
|
||||||
|
CONF.collect.wait_periods)
|
||||||
|
|
||||||
|
|
||||||
class Worker(BaseWorker):
|
class Worker(BaseWorker):
|
||||||
def __init__(self, collector, storage, tenant_id, worker_id):
|
def __init__(self, collector, storage, tenant_id, worker_id):
|
||||||
self._collector = collector
|
self._collector = collector
|
||||||
|
@ -232,11 +241,13 @@ class Worker(BaseWorker):
|
||||||
self._worker_id = worker_id
|
self._worker_id = worker_id
|
||||||
self._conf = ck_utils.load_conf(CONF.collect.metrics_conf)
|
self._conf = ck_utils.load_conf(CONF.collect.metrics_conf)
|
||||||
self._state = state.StateManager()
|
self._state = state.StateManager()
|
||||||
|
self._check_state = functools.partial(
|
||||||
|
_check_state, self, self._period, self._tenant_id)
|
||||||
|
|
||||||
super(Worker, self).__init__(self._tenant_id)
|
super(Worker, self).__init__(self._tenant_id)
|
||||||
|
|
||||||
def _collect(self, metric, start_timestamp):
|
def _collect(self, metric, start_timestamp):
|
||||||
next_timestamp = start_timestamp + self._period
|
next_timestamp = start_timestamp + timedelta(seconds=self._period)
|
||||||
|
|
||||||
raw_data = self._collector.retrieve(
|
raw_data = self._collector.retrieve(
|
||||||
metric,
|
metric,
|
||||||
|
@ -263,7 +274,7 @@ class Worker(BaseWorker):
|
||||||
scope=self._tenant_id,
|
scope=self._tenant_id,
|
||||||
worker=self._worker_id,
|
worker=self._worker_id,
|
||||||
metric=metric,
|
metric=metric,
|
||||||
ts=ck_utils.ts2dt(timestamp))
|
ts=timestamp)
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -273,7 +284,7 @@ class Worker(BaseWorker):
|
||||||
scope=self._tenant_id,
|
scope=self._tenant_id,
|
||||||
worker=self._worker_id,
|
worker=self._worker_id,
|
||||||
metric=metric,
|
metric=metric,
|
||||||
ts=ck_utils.ts2dt(timestamp),
|
ts=timestamp,
|
||||||
e=e)
|
e=e)
|
||||||
)
|
)
|
||||||
# FIXME(peschk_l): here we just exit, and the
|
# FIXME(peschk_l): here we just exit, and the
|
||||||
|
@ -287,15 +298,9 @@ class Worker(BaseWorker):
|
||||||
eventlet.GreenPool(size=CONF.orchestrator.max_greenthreads).imap(
|
eventlet.GreenPool(size=CONF.orchestrator.max_greenthreads).imap(
|
||||||
_get_result, metrics)))
|
_get_result, metrics)))
|
||||||
|
|
||||||
def check_state(self):
|
|
||||||
timestamp = self._state.get_state(self._tenant_id)
|
|
||||||
return ck_utils.check_time_state(timestamp,
|
|
||||||
self._period,
|
|
||||||
CONF.collect.wait_periods)
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
timestamp = self.check_state()
|
timestamp = self._check_state()
|
||||||
if not timestamp:
|
if not timestamp:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -340,6 +345,8 @@ class Orchestrator(cotyledon.Service):
|
||||||
CONF.orchestrator.coordination_url,
|
CONF.orchestrator.coordination_url,
|
||||||
uuidutils.generate_uuid().encode('ascii'))
|
uuidutils.generate_uuid().encode('ascii'))
|
||||||
self.coord.start(start_heart=True)
|
self.coord.start(start_heart=True)
|
||||||
|
self._check_state = functools.partial(
|
||||||
|
_check_state, self, CONF.collect.period)
|
||||||
|
|
||||||
def _init_messaging(self):
|
def _init_messaging(self):
|
||||||
target = oslo_messaging.Target(topic='cloudkitty',
|
target = oslo_messaging.Target(topic='cloudkitty',
|
||||||
|
@ -352,12 +359,6 @@ class Orchestrator(cotyledon.Service):
|
||||||
self.server = messaging.get_server(target, endpoints)
|
self.server = messaging.get_server(target, endpoints)
|
||||||
self.server.start()
|
self.server.start()
|
||||||
|
|
||||||
def _check_state(self, tenant_id):
|
|
||||||
timestamp = self._state.get_state(tenant_id)
|
|
||||||
return ck_utils.check_time_state(timestamp,
|
|
||||||
CONF.collect.period,
|
|
||||||
CONF.collect.wait_periods)
|
|
||||||
|
|
||||||
def process_messages(self):
|
def process_messages(self):
|
||||||
# TODO(sheeprine): Code kept to handle threading and asynchronous
|
# TODO(sheeprine): Code kept to handle threading and asynchronous
|
||||||
# reloading
|
# reloading
|
||||||
|
|
|
@ -14,14 +14,12 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
import abc
|
import abc
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from cloudkitty import utils as ck_utils
|
|
||||||
# from cloudkitty.storage import NoTimeFrame
|
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -39,9 +37,7 @@ class BaseStorage(object):
|
||||||
self._collector = kwargs.get('collector')
|
self._collector = kwargs.get('collector')
|
||||||
|
|
||||||
# State vars
|
# State vars
|
||||||
self.usage_start = {}
|
|
||||||
self.usage_start_dt = {}
|
self.usage_start_dt = {}
|
||||||
self.usage_end = {}
|
|
||||||
self.usage_end_dt = {}
|
self.usage_end_dt = {}
|
||||||
self._has_data = {}
|
self._has_data = {}
|
||||||
|
|
||||||
|
@ -59,17 +55,17 @@ class BaseStorage(object):
|
||||||
Removes the usage from the json data and returns it.
|
Removes the usage from the json data and returns it.
|
||||||
:param json_data: Data to filter.
|
:param json_data: Data to filter.
|
||||||
"""
|
"""
|
||||||
candidate_ts = None
|
candidate = None
|
||||||
candidate_idx = 0
|
candidate_idx = 0
|
||||||
|
|
||||||
for idx, usage in enumerate(json_data):
|
for idx, usage in enumerate(json_data):
|
||||||
usage_ts = usage['period']['begin']
|
usage_ts = usage['period']['begin']
|
||||||
if candidate_ts is None or usage_ts < candidate_ts:
|
if candidate is None or usage_ts < candidate:
|
||||||
candidate_ts = usage_ts
|
candidate = usage_ts
|
||||||
candidate_idx = idx
|
candidate_idx = idx
|
||||||
|
|
||||||
if candidate_ts:
|
if candidate:
|
||||||
return candidate_ts, json_data.pop(candidate_idx)['usage']
|
return candidate, json_data.pop(candidate_idx)['usage']
|
||||||
|
|
||||||
def _pre_commit(self, tenant_id):
|
def _pre_commit(self, tenant_id):
|
||||||
"""Called before every commit.
|
"""Called before every commit.
|
||||||
|
@ -107,8 +103,7 @@ class BaseStorage(object):
|
||||||
:param begin: New usage beginning timestamp.
|
:param begin: New usage beginning timestamp.
|
||||||
:param tenant_id: tenant_id to update.
|
:param tenant_id: tenant_id to update.
|
||||||
"""
|
"""
|
||||||
self.usage_start[tenant_id] = begin
|
self.usage_start_dt[tenant_id] = begin
|
||||||
self.usage_start_dt[tenant_id] = ck_utils.ts2dt(begin)
|
|
||||||
|
|
||||||
def _update_end(self, end, tenant_id):
|
def _update_end(self, end, tenant_id):
|
||||||
"""Update usage_end with a new timestamp.
|
"""Update usage_end with a new timestamp.
|
||||||
|
@ -116,17 +111,14 @@ class BaseStorage(object):
|
||||||
:param end: New usage end timestamp.
|
:param end: New usage end timestamp.
|
||||||
:param tenant_id: tenant_id to update.
|
:param tenant_id: tenant_id to update.
|
||||||
"""
|
"""
|
||||||
self.usage_end[tenant_id] = end
|
self.usage_end_dt[tenant_id] = end
|
||||||
self.usage_end_dt[tenant_id] = ck_utils.ts2dt(end)
|
|
||||||
|
|
||||||
def _clear_usage_info(self, tenant_id):
|
def _clear_usage_info(self, tenant_id):
|
||||||
"""Clear usage information timestamps.
|
"""Clear usage information timestamps.
|
||||||
|
|
||||||
:param tenant_id: tenant_id which information needs to be removed.
|
:param tenant_id: tenant_id which information needs to be removed.
|
||||||
"""
|
"""
|
||||||
self.usage_start.pop(tenant_id, None)
|
|
||||||
self.usage_start_dt.pop(tenant_id, None)
|
self.usage_start_dt.pop(tenant_id, None)
|
||||||
self.usage_end.pop(tenant_id, None)
|
|
||||||
self.usage_end_dt.pop(tenant_id, None)
|
self.usage_end_dt.pop(tenant_id, None)
|
||||||
|
|
||||||
def _check_commit(self, usage_start, tenant_id):
|
def _check_commit(self, usage_start, tenant_id):
|
||||||
|
@ -135,12 +127,13 @@ class BaseStorage(object):
|
||||||
:param usage_start: Start of the period.
|
:param usage_start: Start of the period.
|
||||||
:param tenant_id: tenant_id to check for.
|
:param tenant_id: tenant_id to check for.
|
||||||
"""
|
"""
|
||||||
usage_end = self.usage_end.get(tenant_id)
|
usage_end = self.usage_end_dt.get(tenant_id)
|
||||||
if usage_end is not None and usage_start >= usage_end:
|
if usage_end is not None and usage_start >= usage_end:
|
||||||
self.commit(tenant_id)
|
self.commit(tenant_id)
|
||||||
if self.usage_start.get(tenant_id) is None:
|
if self.usage_start_dt.get(tenant_id) is None:
|
||||||
self._update_start(usage_start, tenant_id)
|
self._update_start(usage_start, tenant_id)
|
||||||
self._update_end(usage_start + self._period, tenant_id)
|
self._update_end(
|
||||||
|
usage_start + timedelta(seconds=self._period), tenant_id)
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def get_state(self, tenant_id=None):
|
def get_state(self, tenant_id=None):
|
||||||
|
|
|
@ -21,7 +21,6 @@ from cloudkitty import db
|
||||||
from cloudkitty.storage.v1 import BaseStorage
|
from cloudkitty.storage.v1 import BaseStorage
|
||||||
from cloudkitty.storage.v1.hybrid import migration
|
from cloudkitty.storage.v1.hybrid import migration
|
||||||
from cloudkitty.storage.v1.hybrid import models
|
from cloudkitty.storage.v1.hybrid import models
|
||||||
from cloudkitty import utils as ck_utils
|
|
||||||
|
|
||||||
|
|
||||||
# NOTE(mc): The deprecated section should be removed in a future release.
|
# NOTE(mc): The deprecated section should be removed in a future release.
|
||||||
|
@ -79,7 +78,7 @@ class HybridStorage(BaseStorage):
|
||||||
q = q.filter(self.state_model.tenant_id == tenant_id)
|
q = q.filter(self.state_model.tenant_id == tenant_id)
|
||||||
q = q.order_by(self.state_model.state.desc())
|
q = q.order_by(self.state_model.state.desc())
|
||||||
r = q.first()
|
r = q.first()
|
||||||
return ck_utils.dt2ts(r.state) if r else None
|
return r.state if r else None
|
||||||
|
|
||||||
def _set_state(self, tenant_id, state):
|
def _set_state(self, tenant_id, state):
|
||||||
self._check_session(tenant_id)
|
self._check_session(tenant_id)
|
||||||
|
|
|
@ -80,7 +80,7 @@ class SQLAlchemyStorage(storage.BaseStorage):
|
||||||
self.frame_model.begin.desc())
|
self.frame_model.begin.desc())
|
||||||
r = q.first()
|
r = q.first()
|
||||||
if r:
|
if r:
|
||||||
return ck_utils.dt2ts(r.begin)
|
return r.begin
|
||||||
|
|
||||||
def get_total(self, begin=None, end=None, tenant_id=None,
|
def get_total(self, begin=None, end=None, tenant_id=None,
|
||||||
service=None, groupby=None):
|
service=None, groupby=None):
|
||||||
|
@ -145,16 +145,16 @@ class SQLAlchemyStorage(storage.BaseStorage):
|
||||||
|
|
||||||
def get_time_frame(self, begin, end, **filters):
|
def get_time_frame(self, begin, end, **filters):
|
||||||
if not begin:
|
if not begin:
|
||||||
begin = ck_utils.get_month_start_timestamp()
|
begin = ck_utils.get_month_start()
|
||||||
if not end:
|
if not end:
|
||||||
end = ck_utils.get_next_month_timestamp()
|
end = ck_utils.get_next_month()
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
q = utils.model_query(
|
q = utils.model_query(
|
||||||
self.frame_model,
|
self.frame_model,
|
||||||
session)
|
session)
|
||||||
q = q.filter(
|
q = q.filter(
|
||||||
self.frame_model.begin >= ck_utils.ts2dt(begin),
|
self.frame_model.begin >= begin,
|
||||||
self.frame_model.end <= ck_utils.ts2dt(end))
|
self.frame_model.end <= end)
|
||||||
for filter_name, filter_value in filters.items():
|
for filter_name, filter_value in filters.items():
|
||||||
if filter_value:
|
if filter_value:
|
||||||
q = q.filter(
|
q = q.filter(
|
||||||
|
|
|
@ -18,7 +18,6 @@ import sqlalchemy
|
||||||
from sqlalchemy.ext import declarative
|
from sqlalchemy.ext import declarative
|
||||||
|
|
||||||
from cloudkitty import json_utils as json
|
from cloudkitty import json_utils as json
|
||||||
from cloudkitty import utils as ck_utils
|
|
||||||
|
|
||||||
|
|
||||||
Base = declarative.declarative_base()
|
Base = declarative.declarative_base()
|
||||||
|
@ -74,8 +73,8 @@ class RatedDataFrame(Base, models.ModelBase):
|
||||||
|
|
||||||
# Time informations
|
# Time informations
|
||||||
period_dict = {}
|
period_dict = {}
|
||||||
period_dict['begin'] = ck_utils.dt2iso(self.begin)
|
period_dict['begin'] = self.begin
|
||||||
period_dict['end'] = ck_utils.dt2iso(self.end)
|
period_dict['end'] = self.end
|
||||||
|
|
||||||
# Add period to the resource informations
|
# Add period to the resource informations
|
||||||
ck_dict = {}
|
ck_dict = {}
|
||||||
|
|
|
@ -133,7 +133,7 @@ class InfluxClient(object):
|
||||||
'measurement': 'dataframes',
|
'measurement': 'dataframes',
|
||||||
'tags': measurement_tags,
|
'tags': measurement_tags,
|
||||||
'fields': measurement_fields,
|
'fields': measurement_fields,
|
||||||
'time': utils.ts2dt(timestamp),
|
'time': timestamp,
|
||||||
})
|
})
|
||||||
if self._autocommit and len(self._points) >= self._chunk_size:
|
if self._autocommit and len(self._points) >= self._chunk_size:
|
||||||
self.commit()
|
self.commit()
|
||||||
|
@ -266,15 +266,6 @@ class InfluxStorage(v2_storage.BaseStorage):
|
||||||
begin = utils.get_month_start()
|
begin = utils.get_month_start()
|
||||||
if not end:
|
if not end:
|
||||||
end = utils.get_next_month()
|
end = utils.get_next_month()
|
||||||
if isinstance(begin, six.text_type):
|
|
||||||
begin = utils.iso2dt(begin)
|
|
||||||
if isinstance(begin, int):
|
|
||||||
begin = utils.ts2dt(begin)
|
|
||||||
if isinstance(end, six.text_type):
|
|
||||||
end = utils.iso2dt(end)
|
|
||||||
if isinstance(end, int):
|
|
||||||
end = utils.ts2dt(end)
|
|
||||||
|
|
||||||
return begin, end
|
return begin, end
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -20,7 +20,6 @@ from oslo_log import log
|
||||||
from cloudkitty import db
|
from cloudkitty import db
|
||||||
from cloudkitty.storage_state import migration
|
from cloudkitty.storage_state import migration
|
||||||
from cloudkitty.storage_state import models
|
from cloudkitty.storage_state import models
|
||||||
from cloudkitty import utils as ck_utils
|
|
||||||
|
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
@ -115,8 +114,19 @@ class StateManager(object):
|
||||||
|
|
||||||
def set_state(self, identifier, state,
|
def set_state(self, identifier, state,
|
||||||
fetcher=None, collector=None, scope_key=None):
|
fetcher=None, collector=None, scope_key=None):
|
||||||
if isinstance(state, int):
|
"""Set the state of a scope.
|
||||||
state = ck_utils.ts2dt(state)
|
|
||||||
|
:param identifier: Identifier of the scope
|
||||||
|
:type identifier: str
|
||||||
|
:param state: state of the scope
|
||||||
|
:type state: datetime.datetime
|
||||||
|
:param fetcher: Fetcher associated to the scope
|
||||||
|
:type fetcher: str
|
||||||
|
:param collector: Collector associated to the scope
|
||||||
|
:type collector: str
|
||||||
|
:param scope_key: scope_key associated to the scope
|
||||||
|
:type scope_key: str
|
||||||
|
"""
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
session.begin()
|
session.begin()
|
||||||
r = self._get_db_item(
|
r = self._get_db_item(
|
||||||
|
@ -140,12 +150,24 @@ class StateManager(object):
|
||||||
|
|
||||||
def get_state(self, identifier,
|
def get_state(self, identifier,
|
||||||
fetcher=None, collector=None, scope_key=None):
|
fetcher=None, collector=None, scope_key=None):
|
||||||
|
"""Get the state of a scope.
|
||||||
|
|
||||||
|
:param identifier: Identifier of the scope
|
||||||
|
:type identifier: str
|
||||||
|
:param fetcher: Fetcher associated to the scope
|
||||||
|
:type fetcher: str
|
||||||
|
:param collector: Collector associated to the scope
|
||||||
|
:type collector: str
|
||||||
|
:param scope_key: scope_key associated to the scope
|
||||||
|
:type scope_key: str
|
||||||
|
:rtype: datetime.datetime
|
||||||
|
"""
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
session.begin()
|
session.begin()
|
||||||
r = self._get_db_item(
|
r = self._get_db_item(
|
||||||
session, identifier, fetcher, collector, scope_key)
|
session, identifier, fetcher, collector, scope_key)
|
||||||
session.close()
|
session.close()
|
||||||
return ck_utils.dt2ts(r.state) if r else None
|
return r.state if r else None
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
migration.upgrade('head')
|
migration.upgrade('head')
|
||||||
|
|
|
@ -19,7 +19,6 @@ import mock
|
||||||
from cloudkitty.collector import monasca as mon_collector
|
from cloudkitty.collector import monasca as mon_collector
|
||||||
from cloudkitty import tests
|
from cloudkitty import tests
|
||||||
from cloudkitty import transformer
|
from cloudkitty import transformer
|
||||||
from cloudkitty import utils
|
|
||||||
|
|
||||||
|
|
||||||
class MonascaCollectorTest(tests.TestCase):
|
class MonascaCollectorTest(tests.TestCase):
|
||||||
|
@ -63,8 +62,8 @@ class MonascaCollectorTest(tests.TestCase):
|
||||||
end = datetime.datetime(2019, 1, 1, 1)
|
end = datetime.datetime(2019, 1, 1, 1)
|
||||||
self.collector._fetch_measures(
|
self.collector._fetch_measures(
|
||||||
'metric_one',
|
'metric_one',
|
||||||
utils.dt2ts(start),
|
start,
|
||||||
utils.dt2ts(end),
|
end,
|
||||||
)
|
)
|
||||||
m.assert_called_once_with(
|
m.assert_called_once_with(
|
||||||
name='metric_one',
|
name='metric_one',
|
||||||
|
@ -84,8 +83,8 @@ class MonascaCollectorTest(tests.TestCase):
|
||||||
end = datetime.datetime(2019, 1, 1, 1)
|
end = datetime.datetime(2019, 1, 1, 1)
|
||||||
self.collector._fetch_measures(
|
self.collector._fetch_measures(
|
||||||
'metric_two',
|
'metric_two',
|
||||||
utils.dt2ts(start),
|
start,
|
||||||
utils.dt2ts(end),
|
end,
|
||||||
)
|
)
|
||||||
m.assert_called_once_with(
|
m.assert_called_once_with(
|
||||||
name='metric_two',
|
name='metric_two',
|
||||||
|
|
|
@ -73,7 +73,7 @@ class PrometheusCollectorTest(tests.TestCase):
|
||||||
)
|
)
|
||||||
mock_get.assert_called_once_with(
|
mock_get.assert_called_once_with(
|
||||||
query,
|
query,
|
||||||
samples.FIRST_PERIOD_END,
|
samples.FIRST_PERIOD_END.isoformat(),
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_format_data_instant_query(self):
|
def test_format_data_instant_query(self):
|
||||||
|
|
|
@ -47,7 +47,6 @@ from cloudkitty.tests.storage.v2 import influx_utils
|
||||||
from cloudkitty.tests import utils as test_utils
|
from cloudkitty.tests import utils as test_utils
|
||||||
from cloudkitty import utils as ck_utils
|
from cloudkitty import utils as ck_utils
|
||||||
|
|
||||||
|
|
||||||
INITIAL_TIMESTAMP = 1420070400
|
INITIAL_TIMESTAMP = 1420070400
|
||||||
|
|
||||||
|
|
||||||
|
@ -294,6 +293,10 @@ class QuoteFakeRPC(BaseFakeRPC):
|
||||||
|
|
||||||
class BaseStorageDataFixture(fixture.GabbiFixture):
|
class BaseStorageDataFixture(fixture.GabbiFixture):
|
||||||
def create_fake_data(self, begin, end, project_id):
|
def create_fake_data(self, begin, end, project_id):
|
||||||
|
if isinstance(begin, int):
|
||||||
|
begin = ck_utils.ts2dt(begin)
|
||||||
|
if isinstance(end, int):
|
||||||
|
end = ck_utils.ts2dt(end)
|
||||||
data = [{
|
data = [{
|
||||||
"period": {
|
"period": {
|
||||||
"begin": begin,
|
"begin": begin,
|
||||||
|
@ -359,7 +362,8 @@ class StorageDataFixture(BaseStorageDataFixture):
|
||||||
for i in range(data_ts,
|
for i in range(data_ts,
|
||||||
data_ts + data_duration,
|
data_ts + data_duration,
|
||||||
3600):
|
3600):
|
||||||
data = self.create_fake_data(i, i + 3600, tenant_list[0])
|
data = self.create_fake_data(
|
||||||
|
i, i + 3600, tenant_list[0])
|
||||||
self.storage.push(data, tenant_list[0])
|
self.storage.push(data, tenant_list[0])
|
||||||
half_duration = int(data_duration / 2)
|
half_duration = int(data_duration / 2)
|
||||||
for i in range(data_ts,
|
for i in range(data_ts,
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
import copy
|
import copy
|
||||||
|
import datetime
|
||||||
import decimal
|
import decimal
|
||||||
|
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
|
@ -25,14 +26,14 @@ TENANT = 'f266f30b11f246b589fd266f85eeec39'
|
||||||
OTHER_TENANT = '8d3ae500-89ea-4142-9c6e-1269db6a0b64'
|
OTHER_TENANT = '8d3ae500-89ea-4142-9c6e-1269db6a0b64'
|
||||||
|
|
||||||
INITIAL_TIMESTAMP = 1420070400
|
INITIAL_TIMESTAMP = 1420070400
|
||||||
FIRST_PERIOD_BEGIN = INITIAL_TIMESTAMP
|
FIRST_PERIOD_BEGIN = ck_utils.ts2dt(INITIAL_TIMESTAMP)
|
||||||
FIRST_PERIOD_BEGIN_ISO = ck_utils.ts2iso(FIRST_PERIOD_BEGIN)
|
FIRST_PERIOD_BEGIN_ISO = ck_utils.dt2iso(FIRST_PERIOD_BEGIN)
|
||||||
FIRST_PERIOD_END = FIRST_PERIOD_BEGIN + 3600
|
FIRST_PERIOD_END = FIRST_PERIOD_BEGIN + datetime.timedelta(seconds=3600)
|
||||||
FIRST_PERIOD_END_ISO = ck_utils.ts2iso(FIRST_PERIOD_END)
|
FIRST_PERIOD_END_ISO = ck_utils.dt2iso(FIRST_PERIOD_END)
|
||||||
SECOND_PERIOD_BEGIN = FIRST_PERIOD_END
|
SECOND_PERIOD_BEGIN = FIRST_PERIOD_END
|
||||||
SECOND_PERIOD_BEGIN_ISO = ck_utils.ts2iso(SECOND_PERIOD_BEGIN)
|
SECOND_PERIOD_BEGIN_ISO = ck_utils.dt2iso(SECOND_PERIOD_BEGIN)
|
||||||
SECOND_PERIOD_END = SECOND_PERIOD_BEGIN + 3600
|
SECOND_PERIOD_END = SECOND_PERIOD_BEGIN + datetime.timedelta(seconds=3600)
|
||||||
SECOND_PERIOD_END_ISO = ck_utils.ts2iso(SECOND_PERIOD_END)
|
SECOND_PERIOD_END_ISO = ck_utils.dt2iso(SECOND_PERIOD_END)
|
||||||
|
|
||||||
COMPUTE_METADATA = {
|
COMPUTE_METADATA = {
|
||||||
'availability_zone': 'nova',
|
'availability_zone': 'nova',
|
||||||
|
@ -223,8 +224,8 @@ DEFAULT_METRICS_CONF = {
|
||||||
def split_storage_data(raw_data):
|
def split_storage_data(raw_data):
|
||||||
final_data = []
|
final_data = []
|
||||||
for frame in raw_data:
|
for frame in raw_data:
|
||||||
frame['period']['begin'] = ck_utils.ts2iso(frame['period']['begin'])
|
frame['period']['begin'] = ck_utils.dt2iso(frame['period']['begin'])
|
||||||
frame['period']['end'] = ck_utils.ts2iso(frame['period']['end'])
|
frame['period']['end'] = ck_utils.dt2iso(frame['period']['end'])
|
||||||
usage_buffer = frame.pop('usage')
|
usage_buffer = frame.pop('usage')
|
||||||
# Sort to have a consistent result as we are converting it to a list
|
# Sort to have a consistent result as we are converting it to a list
|
||||||
for service, data in sorted(usage_buffer.items()):
|
for service, data in sorted(usage_buffer.items()):
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
import copy
|
import copy
|
||||||
|
import datetime
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
import testscenarios
|
import testscenarios
|
||||||
|
@ -22,7 +23,6 @@ from cloudkitty import storage
|
||||||
from cloudkitty import tests
|
from cloudkitty import tests
|
||||||
from cloudkitty.tests import samples
|
from cloudkitty.tests import samples
|
||||||
from cloudkitty.tests import utils as test_utils
|
from cloudkitty.tests import utils as test_utils
|
||||||
from cloudkitty import utils as ck_utils
|
|
||||||
|
|
||||||
|
|
||||||
class StorageTest(tests.TestCase):
|
class StorageTest(tests.TestCase):
|
||||||
|
@ -73,7 +73,8 @@ class StorageDataframeTest(StorageTest):
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
storage.NoTimeFrame,
|
storage.NoTimeFrame,
|
||||||
self.storage.retrieve,
|
self.storage.retrieve,
|
||||||
begin=samples.FIRST_PERIOD_BEGIN - 3600,
|
begin=(samples.FIRST_PERIOD_BEGIN
|
||||||
|
- datetime.timedelta(seconds=3600)),
|
||||||
end=samples.FIRST_PERIOD_BEGIN)
|
end=samples.FIRST_PERIOD_BEGIN)
|
||||||
|
|
||||||
def test_get_frame_filter_outside_data(self):
|
def test_get_frame_filter_outside_data(self):
|
||||||
|
@ -81,7 +82,8 @@ class StorageDataframeTest(StorageTest):
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
storage.NoTimeFrame,
|
storage.NoTimeFrame,
|
||||||
self.storage.retrieve,
|
self.storage.retrieve,
|
||||||
begin=samples.FIRST_PERIOD_BEGIN - 3600,
|
begin=(samples.FIRST_PERIOD_BEGIN
|
||||||
|
- datetime.timedelta(seconds=3600)),
|
||||||
end=samples.FIRST_PERIOD_BEGIN)
|
end=samples.FIRST_PERIOD_BEGIN)
|
||||||
|
|
||||||
def test_get_frame_without_filter_but_timestamp(self):
|
def test_get_frame_without_filter_but_timestamp(self):
|
||||||
|
@ -132,8 +134,8 @@ class StorageTotalTest(StorageTest):
|
||||||
|
|
||||||
# Total
|
# Total
|
||||||
def test_get_empty_total(self):
|
def test_get_empty_total(self):
|
||||||
begin = ck_utils.ts2dt(samples.FIRST_PERIOD_BEGIN - 3600)
|
begin = samples.FIRST_PERIOD_BEGIN - datetime.timedelta(seconds=3600)
|
||||||
end = ck_utils.ts2dt(samples.FIRST_PERIOD_BEGIN)
|
end = samples.FIRST_PERIOD_BEGIN
|
||||||
self.insert_data()
|
self.insert_data()
|
||||||
total = self.storage.total(
|
total = self.storage.total(
|
||||||
begin=begin,
|
begin=begin,
|
||||||
|
@ -144,8 +146,8 @@ class StorageTotalTest(StorageTest):
|
||||||
self.assertEqual(end, total[0]["end"])
|
self.assertEqual(end, total[0]["end"])
|
||||||
|
|
||||||
def test_get_total_without_filter_but_timestamp(self):
|
def test_get_total_without_filter_but_timestamp(self):
|
||||||
begin = ck_utils.ts2dt(samples.FIRST_PERIOD_BEGIN)
|
begin = samples.FIRST_PERIOD_BEGIN
|
||||||
end = ck_utils.ts2dt(samples.SECOND_PERIOD_END)
|
end = samples.SECOND_PERIOD_END
|
||||||
self.insert_data()
|
self.insert_data()
|
||||||
total = self.storage.total(
|
total = self.storage.total(
|
||||||
begin=begin,
|
begin=begin,
|
||||||
|
@ -157,8 +159,8 @@ class StorageTotalTest(StorageTest):
|
||||||
self.assertEqual(end, total[0]["end"])
|
self.assertEqual(end, total[0]["end"])
|
||||||
|
|
||||||
def test_get_total_filtering_on_one_period(self):
|
def test_get_total_filtering_on_one_period(self):
|
||||||
begin = ck_utils.ts2dt(samples.FIRST_PERIOD_BEGIN)
|
begin = samples.FIRST_PERIOD_BEGIN
|
||||||
end = ck_utils.ts2dt(samples.FIRST_PERIOD_END)
|
end = samples.FIRST_PERIOD_END
|
||||||
self.insert_data()
|
self.insert_data()
|
||||||
total = self.storage.total(
|
total = self.storage.total(
|
||||||
begin=begin,
|
begin=begin,
|
||||||
|
@ -169,8 +171,8 @@ class StorageTotalTest(StorageTest):
|
||||||
self.assertEqual(end, total[0]["end"])
|
self.assertEqual(end, total[0]["end"])
|
||||||
|
|
||||||
def test_get_total_filtering_on_one_period_and_one_tenant(self):
|
def test_get_total_filtering_on_one_period_and_one_tenant(self):
|
||||||
begin = ck_utils.ts2dt(samples.FIRST_PERIOD_BEGIN)
|
begin = samples.FIRST_PERIOD_BEGIN
|
||||||
end = ck_utils.ts2dt(samples.FIRST_PERIOD_END)
|
end = samples.FIRST_PERIOD_END
|
||||||
self.insert_data()
|
self.insert_data()
|
||||||
filters = {'project_id': self._tenant_id}
|
filters = {'project_id': self._tenant_id}
|
||||||
total = self.storage.total(
|
total = self.storage.total(
|
||||||
|
@ -184,8 +186,8 @@ class StorageTotalTest(StorageTest):
|
||||||
self.assertEqual(end, total[0]["end"])
|
self.assertEqual(end, total[0]["end"])
|
||||||
|
|
||||||
def test_get_total_filtering_on_service(self):
|
def test_get_total_filtering_on_service(self):
|
||||||
begin = ck_utils.ts2dt(samples.FIRST_PERIOD_BEGIN)
|
begin = samples.FIRST_PERIOD_BEGIN
|
||||||
end = ck_utils.ts2dt(samples.FIRST_PERIOD_END)
|
end = samples.FIRST_PERIOD_END
|
||||||
self.insert_data()
|
self.insert_data()
|
||||||
total = self.storage.total(
|
total = self.storage.total(
|
||||||
begin=begin,
|
begin=begin,
|
||||||
|
@ -198,8 +200,8 @@ class StorageTotalTest(StorageTest):
|
||||||
self.assertEqual(end, total[0]["end"])
|
self.assertEqual(end, total[0]["end"])
|
||||||
|
|
||||||
def test_get_total_groupby_tenant(self):
|
def test_get_total_groupby_tenant(self):
|
||||||
begin = ck_utils.ts2dt(samples.FIRST_PERIOD_BEGIN)
|
begin = samples.FIRST_PERIOD_BEGIN
|
||||||
end = ck_utils.ts2dt(samples.SECOND_PERIOD_END)
|
end = samples.SECOND_PERIOD_END
|
||||||
self.insert_data()
|
self.insert_data()
|
||||||
total = self.storage.total(
|
total = self.storage.total(
|
||||||
begin=begin,
|
begin=begin,
|
||||||
|
@ -216,8 +218,8 @@ class StorageTotalTest(StorageTest):
|
||||||
self.assertEqual(end, total[1]["end"])
|
self.assertEqual(end, total[1]["end"])
|
||||||
|
|
||||||
def test_get_total_groupby_restype(self):
|
def test_get_total_groupby_restype(self):
|
||||||
begin = ck_utils.ts2dt(samples.FIRST_PERIOD_BEGIN)
|
begin = samples.FIRST_PERIOD_BEGIN
|
||||||
end = ck_utils.ts2dt(samples.SECOND_PERIOD_END)
|
end = samples.SECOND_PERIOD_END
|
||||||
self.insert_data()
|
self.insert_data()
|
||||||
total = self.storage.total(
|
total = self.storage.total(
|
||||||
begin=begin,
|
begin=begin,
|
||||||
|
@ -234,8 +236,8 @@ class StorageTotalTest(StorageTest):
|
||||||
self.assertEqual(end, total[1]["end"])
|
self.assertEqual(end, total[1]["end"])
|
||||||
|
|
||||||
def test_get_total_groupby_tenant_and_restype(self):
|
def test_get_total_groupby_tenant_and_restype(self):
|
||||||
begin = ck_utils.ts2dt(samples.FIRST_PERIOD_BEGIN)
|
begin = samples.FIRST_PERIOD_BEGIN
|
||||||
end = ck_utils.ts2dt(samples.SECOND_PERIOD_END)
|
end = samples.SECOND_PERIOD_END
|
||||||
self.insert_data()
|
self.insert_data()
|
||||||
total = self.storage.total(
|
total = self.storage.total(
|
||||||
begin=begin,
|
begin=begin,
|
||||||
|
|
|
@ -137,13 +137,10 @@ class FakeInfluxClient(InfluxClient):
|
||||||
|
|
||||||
def delete(self, begin, end, filters):
|
def delete(self, begin, end, filters):
|
||||||
|
|
||||||
beg = utils.dt2ts(begin) if begin else None
|
|
||||||
end = utils.dt2ts(end) if end else None
|
|
||||||
|
|
||||||
def __filter_func(elem):
|
def __filter_func(elem):
|
||||||
|
|
||||||
def __time(elem):
|
def __time(elem):
|
||||||
return ((beg and beg > elem['time'])
|
return ((begin and begin > elem['time'])
|
||||||
or (end and end <= elem['time']))
|
or (end and end <= elem['time']))
|
||||||
|
|
||||||
def __filt(elem):
|
def __filt(elem):
|
||||||
|
|
|
@ -28,10 +28,10 @@ def generate_v2_storage_data(min_length=10,
|
||||||
project_ids=None,
|
project_ids=None,
|
||||||
start=datetime(2018, 1, 1),
|
start=datetime(2018, 1, 1),
|
||||||
end=datetime(2018, 1, 1, 1)):
|
end=datetime(2018, 1, 1, 1)):
|
||||||
if isinstance(start, datetime):
|
if isinstance(start, int):
|
||||||
start = ck_utils.dt2ts(start)
|
start = ck_utils.ts2dt(start)
|
||||||
if isinstance(end, datetime):
|
if isinstance(end, int):
|
||||||
end = ck_utils.dt2ts(end)
|
end = ck_utils.ts2dt(end)
|
||||||
|
|
||||||
if not project_ids:
|
if not project_ids:
|
||||||
project_ids = [uuidutils.generate_uuid() for i in range(nb_projects)]
|
project_ids = [uuidutils.generate_uuid() for i in range(nb_projects)]
|
||||||
|
|
|
@ -213,15 +213,29 @@ def refresh_stevedore(namespace=None):
|
||||||
|
|
||||||
|
|
||||||
def check_time_state(timestamp=None, period=0, wait_periods=0):
|
def check_time_state(timestamp=None, period=0, wait_periods=0):
|
||||||
if not timestamp:
|
"""Checks the state of a timestamp compared to the current time.
|
||||||
return get_month_start_timestamp()
|
|
||||||
|
|
||||||
now = utcnow_ts()
|
Returns the next timestamp based on the current timestamp and the period if
|
||||||
next_timestamp = timestamp + period
|
the next timestamp is inferior to the current time and the waiting period
|
||||||
wait_time = wait_periods * period
|
or None if not.
|
||||||
if next_timestamp + wait_time < now:
|
|
||||||
|
:param timestamp: Current timestamp
|
||||||
|
:type timestamp: datetime.datetime
|
||||||
|
:param period: Period, in seconds
|
||||||
|
:type period: int
|
||||||
|
:param wait_periods: periods to wait before the current timestamp.
|
||||||
|
:type wait_periods: int
|
||||||
|
:rtype: datetime.datetime
|
||||||
|
"""
|
||||||
|
if not timestamp:
|
||||||
|
return get_month_start()
|
||||||
|
|
||||||
|
period_delta = datetime.timedelta(seconds=period)
|
||||||
|
next_timestamp = timestamp + period_delta
|
||||||
|
wait_time = wait_periods * period_delta
|
||||||
|
if next_timestamp + wait_time < utcnow():
|
||||||
return next_timestamp
|
return next_timestamp
|
||||||
return 0
|
return None
|
||||||
|
|
||||||
|
|
||||||
def load_conf(conf_path):
|
def load_conf(conf_path):
|
||||||
|
|
Loading…
Reference in New Issue