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_durationmax_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-createPOST /check-updatePOST /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.