Apply my comments from the original patch [1] and add unit tests. [1] https://review.opendev.org/c/openstack/blazar/+/781917 Change-Id: I116aad6677423aedb5dda48f06b36afc32819ba8
5.2 KiB
Usage Enforcement
Synopsis
Usage enforcement and lease constraints can be implemented by operators via custom usage enforcement filters or an external service.
Description
Usage enforcement filters are called on lease_create
,
lease_update
and on_end
operations. The
filters check whether or not lease values or allocation criteria pass
admin defined thresholds. There are currently two filters provided
out-of-the-box. MaxLeaseDurationFilter
restricts the
duration of leases. ExternalServiceFilter
calls a
third-party service for implementing policies using a URL configured in
blazar.conf
.
Options
All filters are a subclass of the BaseFilter class located in
blazar/enforcement/filter/base_filter.py
. Custom filters
must implement methods for check_create
,
check_update
, and on_end
. The
MaxLeaseDurationFilter
is a good example to follow. Filters
are enabled in blazar.conf
under the
[enforcement]
group. For example, enabling the
MaxLeaseDurationFilter
to limit lease durations to only one
day would work as follows:
[enforcement]
enabled_filters = MaxLeaseDurationFilter
max_lease_duration = 86400
Do note that filter config options follow filter names - the prefix
is always the snake case of the filter name
(MaxLeaseDurationFilter
becomes
max_lease_duration
; in this case it is special that there
is nothing beyond the prefix but there is also
max_lease_duration_exempt_project_ids
).
MaxLeaseDurationFilter
This filter simply examines the lease start_date
and
end_date
attributes and rejects the lease if its duration
exceeds a threshold. It supports two configuration options:
max_lease_duration
max_lease_duration_exempt_project_ids
See the ../configuration/blazar-conf
page for a description of
these options.
ExternalServiceFilter
This filter delegates the decision for each API to an external HTTP
service. The service must use token-based authentication, accepting (or
ignoring) the static token sent by Blazar in the
X-Auth-Token
header. The following endpoints should be
implemented:
POST /check-create
POST /check-update
POST /on-end
The exact URLs can be overridden and not all have to be used (although we imagine a proper implementation requires at least both checks unless lease updates are disabled in the first place).
The external service should return 204 No Content
if the
parameters meet defined criteria and 403 Forbidden
if not.
The service may send a JSON body response with the
403 Forbidden
reply, including the rejection reasoning in
the field named message
as in:
{
"message": "You shall not pass!"
}
An example of data the external service will receive in a request body (do note all dates and times are encoded as strings following the ISO8601 standard that is expected in JSON to represent dates and times):
- Request example:
{
"context": {
"user_id": "c631173e-dec0-4bb7-a0c3-f7711153c06c",
"project_id": "a0b86a98-b0d3-43cb-948e-00689182efd4",
"auth_url": "https://api.example.com:5000/v3",
"region_name": "RegionOne"
},
"current_lease": {
"start_date": "2020-05-13T00:00:00.012345+02:00",
"end_time": "2020-05-14T23:59:00.012345+02:00",
"reservations": [
{
"resource_type": "physical:host",
"min": 1,
"max": 2,
"hypervisor_properties": "[]",
"resource_properties": "[\"==\", \"$availability_zone\", \"az1\"]",
"allocations": [
{
"id": "1",
"hypervisor_hostname": "32af5a7a-e7a3-4883-a643-828e3f63bf54",
"extra": {
"availability_zone": "az1"
}
}
]
}
]
},
"lease": {
"start_date": "2020-05-13T00:00:00.012345+02:00",
"end_time": "2020-05-14T23:59:00.012345+02:00",
"reservations": [
{
"resource_type": "physical:host",
"min": 2,
"max": 3,
"hypervisor_properties": "[]",
"resource_properties": "[\"==\", \"$availability_zone\", \"az1\"]",
"allocations": [
{
"id": "1",
"hypervisor_hostname": "32af5a7a-e7a3-4883-a643-828e3f63bf54",
"extra": {
"availability_zone": "az1"
}
},
{
"id": "2",
"hypervisor_hostname": "af69aabd-8386-4053-a6dd-1a983787bd7f",
"extra": {
"availability_zone": "az1"
}
}
]
}
]
}
}
The current_lease
field is present only in
check-update
requests and describes the existing lease. In
both checks the lease
field describes the new lease. In
on-end
, the lease
field describes the lease
that has just ended.
There is no guarantee on the delivery of the on-end
event and it should be considered an optimisation rather than a reliable
mechanism.