Skip to content

Commit 0c0e345

Browse files
committed
Additional fixes
1 parent 3a4970a commit 0c0e345

File tree

12 files changed

+332
-75
lines changed

12 files changed

+332
-75
lines changed

blazar/enforcement/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2013 Bull.
1+
# Copyright (c) 2020 University of Chicago.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.

blazar/enforcement/enforcement.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2013 Bull.
1+
# Copyright (c) 2020 University of Chicago.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
1414
# limitations under the License.
1515

1616
from blazar.enforcement import filters
17+
from blazar.utils.openstack import base
1718

1819
from oslo_config import cfg
1920
from oslo_log import log as logging
@@ -23,9 +24,7 @@
2324
enforcement_opts = [
2425
cfg.ListOpt('enabled_filters',
2526
default=[],
26-
help='Maximum lease duration in seconds. If this is set to -1,'
27-
' there is not limit. For active leases being updated, '
28-
'the limit applies between now and the new end date.'),
27+
help='List of enabled usage enforcement filters.'),
2928
]
3029

3130
CONF.register_opts(enforcement_opts, group='enforcement')
@@ -46,12 +45,9 @@ def load_filters(self):
4645
def format_context(self, context):
4746
ctx = context.to_dict()
4847
region_name = CONF.os_region_name
49-
identity_endpoints = [
50-
x['endpoints'] for x in ctx['service_catalog']
51-
if x['type'] == 'identity'][0]
52-
auth_url = [
53-
x['url'] for x in identity_endpoints
54-
if (x['interface'] == 'public' and x['region'] == region_name)][0]
48+
auth_url = base.url_for(
49+
ctx['service_catalog'], CONF.identity_service,
50+
os_region_name=region_name)
5551

5652
return dict(user_id=ctx['user_id'], project_id=ctx['project_id'],
5753
auth_url=auth_url, region_name=region_name)
@@ -64,7 +60,7 @@ def format_lease(self, lease_values, reservations, allocations):
6460
res = reservation.copy()
6561
resource_type = res['resource_type']
6662
res['allocations'] = allocations[resource_type]
67-
lease['reservations'] = reservations
63+
lease['reservations'].append(reservations)
6864

6965
return lease
7066

blazar/enforcement/filters/base_filter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2013 Bull.
1+
# Copyright (c) 2020 University of Chicago.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.

blazar/enforcement/filters/external_service_filter.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2013 Bull.
1+
# Copyright (c) 2020 University of Chicago.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -15,9 +15,9 @@
1515

1616
import requests
1717

18+
from blazar.enforcement.filters import base_filter
1819
from blazar import exceptions
1920
from blazar.i18n import _
20-
from blazar.enforcement.filters import base_filter
2121

2222
from oslo_config import cfg
2323
from oslo_log import log as logging
@@ -30,6 +30,7 @@ class ExternalServiceUnsupportedHTTPResponse(exceptions.BlazarExceptions):
3030
msg_fmt = _('External Service Filter returned a %(status)s http response. '
3131
'Only 204 and 403 responses are supported.')
3232

33+
3334
class ExternalServiceFilterException(exceptions.BlazarExceptions):
3435
code = 400
3536
msg_fmt = _('%(message)s')
@@ -84,7 +85,6 @@ def check_create(self, context, lease_values):
8485

8586
self.post(path, body)
8687

87-
8888
def check_update(self, context, current_lease_values, new_lease_values):
8989
if self.external_service_endpoint:
9090
path = '/v1/check-update'

blazar/enforcement/filters/max_reservation_length_filter.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2013 Bull.
1+
# Copyright (c) 2020 University of Chicago.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -13,11 +13,12 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
from datetime import datetime, timedelta
16+
from datetime import datetime
17+
from datetime import timedelta
1718

19+
from blazar.enforcement.filters import base_filter
1820
from blazar import exceptions
1921
from blazar.i18n import _
20-
from blazar.enforcement.filters import base_filter
2122

2223
from oslo_config import cfg
2324
from oslo_log import log as logging

blazar/manager/service.py

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,44 @@ def _date_from_string(self, date_string, date_format=LEASE_DATE_FORMAT):
219219
date_format=date_format)
220220
return date
221221

222+
def _parse_lease_dates(self, start_date, end_date):
223+
now = datetime.datetime.utcnow()
224+
now = datetime.datetime(now.year,
225+
now.month,
226+
now.day,
227+
now.hour,
228+
now.minute)
229+
if start_date == 'now':
230+
start_date = now
231+
else:
232+
start_date = self._date_from_string(start_date)
233+
if end_date == 'now':
234+
end_date = now
235+
else:
236+
end_date = self._date_from_string(end_date)
237+
238+
return start_date, end_date, now
239+
240+
def _check_for_invalid_date_inputs(self, lease, values, now):
241+
if (lease['start_date'] < now and
242+
values['start_date'] != lease['start_date']):
243+
raise common_ex.InvalidInput(
244+
'Cannot modify the start date of already started leases')
245+
246+
if (lease['start_date'] > now and
247+
values['start_date'] < now):
248+
raise common_ex.InvalidInput(
249+
'Start date must be later than current date')
250+
251+
if lease['end_date'] < now:
252+
raise common_ex.InvalidInput(
253+
'Terminated leases can only be renamed')
254+
255+
if (values['end_date'] < now or
256+
values['end_date'] < values['start_date']):
257+
raise common_ex.InvalidInput(
258+
'End date must be later than current and start date')
259+
222260
def validate_params(self, values, required_params):
223261
if isinstance(required_params, list):
224262
required_params = set(required_params)
@@ -253,20 +291,8 @@ def create_lease(self, lease_values):
253291
self.validate_params(res, ['resource_type'])
254292

255293
# Create the lease without the reservations
256-
start_date = lease_values['start_date']
257-
end_date = lease_values['end_date']
258-
259-
now = datetime.datetime.utcnow()
260-
now = datetime.datetime(now.year,
261-
now.month,
262-
now.day,
263-
now.hour,
264-
now.minute)
265-
if start_date == 'now':
266-
start_date = now
267-
else:
268-
start_date = self._date_from_string(start_date)
269-
end_date = self._date_from_string(end_date)
294+
start_date, end_date, now = self._parse_lease_dates(
295+
lease_values['start_date'], lease_values['end_date'])
270296

271297
if start_date < now:
272298
raise common_ex.InvalidInput(
@@ -384,42 +410,13 @@ def update_lease(self, lease_id, values):
384410
datetime.datetime.strftime(lease['end_date'], LEASE_DATE_FORMAT))
385411
before_end_date = values.get('before_end_date', None)
386412

387-
now = datetime.datetime.utcnow()
388-
now = datetime.datetime(now.year,
389-
now.month,
390-
now.day,
391-
now.hour,
392-
now.minute)
393-
if start_date == 'now':
394-
start_date = now
395-
else:
396-
start_date = self._date_from_string(start_date)
397-
if end_date == 'now':
398-
end_date = now
399-
else:
400-
end_date = self._date_from_string(end_date)
413+
start_date, end_date, now = self._parse_lease_dates(start_date,
414+
end_date)
401415

402416
values['start_date'] = start_date
403417
values['end_date'] = end_date
404418

405-
if (lease['start_date'] < now and
406-
values['start_date'] != lease['start_date']):
407-
raise common_ex.InvalidInput(
408-
'Cannot modify the start date of already started leases')
409-
410-
if (lease['start_date'] > now and
411-
values['start_date'] < now):
412-
raise common_ex.InvalidInput(
413-
'Start date must be later than current date')
414-
415-
if lease['end_date'] < now:
416-
raise common_ex.InvalidInput(
417-
'Terminated leases can only be renamed')
418-
419-
if (values['end_date'] < now or
420-
values['end_date'] < values['start_date']):
421-
raise common_ex.InvalidInput(
422-
'End date must be later than current and start date')
419+
self._check_for_invalid_date_inputs(lease, values, now)
423420

424421
with trusts.create_ctx_from_trust(lease['trust_id']) as ctx:
425422
if before_end_date:
@@ -478,6 +475,9 @@ def update_lease(self, lease_id, values):
478475
resource_type = v.get('resource_type',
479476
reservation['resource_type'])
480477

478+
if resource_type != reservation['resource_type']:
479+
raise exceptions.CantUpdateParameter(
480+
param='resource_type')
481481
self.plugins[resource_type].update_reservation(
482482
reservation['id'], v)
483483

@@ -584,7 +584,7 @@ def end_lease(self, lease_id, event_id):
584584
lease = self.get_lease(lease_id)
585585
allocations = self._existing_allocations(lease['reservations'])
586586

587-
with trusts.create_ctx_from_trust(lease['trust_id']) as ctx:
587+
with trusts.create_ctx_from_trust(lease['trust_id']):
588588
self.enforcement.on_end(context.current(), lease, allocations)
589589
self._basic_action(lease_id, event_id, 'on_end',
590590
status.reservation.DELETED)

blazar/plugins/instances/instance_plugin.py

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
INSTANCE_DELETION_TIMEOUT = 10 * 60 * 1000 # 10 minutes
4545

4646
NONE_VALUES = ('None', 'none', None)
47+
QUERY_TYPE_ALLOCATION = 'allocation'
4748

4849

4950
class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
@@ -138,6 +139,43 @@ def get_hosts_list(self, host_info, cpus, memory, disk):
138139
used_disk += disk
139140
return hosts_list
140141

142+
def allocation_candidates(self, reservation):
143+
return self.pickup_hosts(self, None, reservation)['added']
144+
145+
def list_allocations(self, query):
146+
hosts_id_list = [h['id'] for h in db_api.host_list()]
147+
options = self.get_query_options(query, QUERY_TYPE_ALLOCATION)
148+
149+
hosts_allocations = self.query_allocations(hosts_id_list, **options)
150+
return [{"resource_id": host, "reservations": allocs}
151+
for host, allocs in hosts_allocations.items()]
152+
153+
def query_allocations(self, hosts, lease_id=None, reservation_id=None):
154+
"""Return dict of host and its allocations.
155+
156+
The list element forms
157+
{
158+
'host-id': [
159+
{
160+
'lease_id': lease_id,
161+
'id': reservation_id
162+
},
163+
]
164+
}.
165+
"""
166+
start = datetime.datetime.utcnow()
167+
end = datetime.date.max
168+
169+
# To reduce overhead, this method only executes one query
170+
# to get the allocation information
171+
rsv_lease_host = db_utils.get_reservation_allocations_by_host_ids(
172+
hosts, start, end, lease_id, reservation_id)
173+
174+
hosts_allocs = collections.defaultdict(list)
175+
for rsv, lease, host in rsv_lease_host:
176+
hosts_allocs[host].append({'lease_id': lease, 'id': rsv})
177+
return hosts_allocs
178+
141179
def query_available_hosts(self, cpus=None, memory=None, disk=None,
142180
resource_properties=None,
143181
start_date=None, end_date=None,
@@ -759,12 +797,12 @@ def _post_reallocate(self, reservation, lease, host_id, num):
759797
LOG.warn('Resource changed for reservation %s (lease: %s).',
760798
reservation['id'], lease['name'])
761799

762-
def get(self, resource_id):
763-
return None
764-
765-
def query_allocations(self, resource_id_list, lease_id=None,
766-
reservation_id=None):
767-
return None
768-
769-
def allocation_candidates(self, lease_values):
770-
return None
800+
def get(self, host_id):
801+
host = db_api.host_get(host_id)
802+
extra_capabilities = self._get_extra_capabilities(host_id)
803+
if host is not None and extra_capabilities:
804+
res = host.copy()
805+
res.update(extra_capabilities)
806+
return res
807+
else:
808+
return host

blazar/tests/enforcement/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)