Documentation
¶
Overview ¶
Package liquid contains the API specification for LIQUID (the Limes Interface for Quota and Usage Interrogation and Discovery).
Limes expects OpenStack services to expose this interface either natively or through an adapter. The interface allows Limes to retrieve quota and usage data, and optionally capacity data, from the respective OpenStack service. Limes will also use the interface to set quota within the service.
Naming conventions ¶
Throughout this document:
- "LIQUID" (upper case) refers to the REST interface defined by this document.
- "A liquid" (lower case) refers to a server implementing LIQUID.
- "The liquid's service" refers to the OpenStack service that the liquid is a part of or connected to.
Each liquid provides access to zero or more resources and zero or more rates:
- A resource is any countable or measurable kind of entity managed by the liquid's service.
- A rate is any countable or measurable series of events or transfers managed by the liquid's service.
Limes discovers liquids through the Keystone service catalog. Each liquid should be registered there with a service type that has the prefix "liquid-". If a liquid uses vendor-specific APIs to interact with its service, its service type may include the vendor name.
Inside a resource: Usage, quota, capacity, overcommit ¶
Resources describe objects that are provisioned at some point and then kept around until they are later deleted. Examples of resources include VMs in a compute service, volumes in a storage service, or floating IPs in a network service. (This does not mean that each individual floating IP is a resource. The entire concept of "floating IPs" is the resource.) Resource usage and capacity is always measured at a specific point in time, like for the Prometheus metric type "gauge".
All resources report a usage value for each Keystone project. This describes how much of the resource is used by objects created within the project. For example, the usage for the compute resource "cores" is the sum of all vCPUs allocated to each VM in that project.
Some resources maintain a quota value for each Keystone project. If so, the usage value must be meaningfully connected to the quota value: Provisioning of new assets shall be rejected with "quota exceeded" if and only if usage would exceed quota afterwards.
Some resources report a capacity value that applies to the entire OpenStack deployment. For example, the capacity for the compute resource "cores" would be the total amount of CPU cores available across all hypervisors.
This capacity value, as it is reported by the liquid, is also called "raw capacity". Limes may be configured to apply an "overcommit factor" to obtain an "effective capacity". For example, the compute resource "cores" is often overcommitted because most users do not put 100% load on their VMs all the time. In this case, quota and usage values are in terms of effective capacity, even though the capacity value is in terms of raw capacity.
Capacity and usage may be AZ-aware, in which case one value will be reported per availability zone (AZ). Quota is only optionally modelled as AZ-aware since there are no OpenStack services that support AZ-aware quota at this time.
Inside a rate: Usage ¶
Rates are measurements that only ever increase over time, similar to the Prometheus metric type "counter". For example, if a compute service has the resource "VMs", it might have rates like "VM creations" or "VM deletions". Rates describe countable events like in this example, or measurable transfers like "bytes received" or "bytes transferred" on network links.
All rates report a usage value for each Keystone project. Usage for each project must increase monotonically over time. Usage may be AZ-aware, in which case one value will be reported per availability zone (AZ).
API structure ¶
LIQUID is structured as a REST-like HTTP API akin to those of the various OpenStack services. Like with any other OpenStack API, the client (i.e. Limes) authenticates to the liquid by providing its Keystone token in the HTTP header "X-Auth-Token". Requests without a valid token shall be rejected with status 401 (Unauthorized). Requests with a valid token that confers insufficient access shall be rejected with status 403 (Forbidden).
Each individual endpoint is documented in a section of this docstring whose title starts with "Endpoint:". Unless noted otherwise, a liquid must implement all documented endpoints. The full URL of the endpoint is obtained by appending the subpath from the section header to the liquid's base URL from the Keystone service catalog.
The documentation for an endpoint may refer to a request body being expected or a response body being generated on success. In all such cases, the request or response body will be encoded as "Content-Type: application/json". The structure of the payload must conform to how the referenced Go type would be serialized by the Go standard library's "encoding/json" package.
When producing a successful response, the status code shall be 200 (OK) unless noted otherwise. When producing an error response (with a status code between 400 and 599), the liquid shall include a response body of "Content-Type: text/plain" to indicate the error.
Metrics ¶
While measuring quota, usage and capacity on behalf of Limes, liquids may obtain other metrics that may be useful to report to the OpenStack operator. LIQUID offers an optional facility to report metrics like this to Limes as part of the regular quota/usage and capacity reports. These metrics will be stored in the Limes database and then collectively forwarded to a metrics database like Prometheus. This delivery method is designed to ensure that liquids can be operated without their own persistent storage.
LIQUID structures metrics in the same way as the OpenMetrics format used by Prometheus:
- A "metric" is a floating-point-valued measurement with an optional set of labels. A label set is a map of string keys to string values.
- A "metric family" is a named set of metrics where the labelset of each metric must have the same keys, but a distinct set of values.
Endpoint: GET /v1/info ¶
Returns information about the OpenStack service and the resources available within it.
- On success, the response body payload must be of type ServiceInfo.
Endpoint: POST /v1/report-capacity ¶
Reports available capacity across all resources of this service.
- The request body payload must be of type ServiceCapacityRequest.
- On success, the response body payload must be of type ServiceCapacityReport.
Endpoint: POST /v1/projects/:uuid/report-usage ¶
Reports usage data (as well as applicable quotas) within a project across all resources of this service.
- The ":uuid" parameter in the request path must refer to a project ID known to Keystone.
- The request body payload must be of type ServiceUsageRequest.
- On success, the response body payload must be of type ServiceUsageReport.
Endpoint: PUT /v1/projects/:uuid/quota ¶
Updates quota within a project across all resources of this service.
- The ":uuid" parameter in the request path must refer to a project ID known to Keystone.
- The request body payload must be of type ServiceQuotaRequest.
- On success, the response body shall be empty and status 204 (No Content) shall be returned.
Index ¶
- func InAnyAZ[T any](value T) map[AvailabilityZone]*T
- func ValidateCapacityReport(report ServiceCapacityReport, req ServiceCapacityRequest, info ServiceInfo) error
- func ValidateServiceInfo(srv ServiceInfo) error
- func ValidateUsageReport(report ServiceUsageReport, req ServiceUsageRequest, info ServiceInfo) error
- type AZRateUsageReport
- type AZResourceCapacityReport
- type AZResourceQuotaRequest
- type AZResourceUsageReport
- type AvailabilityZone
- type DomainMetadata
- type Metric
- type MetricFamilyInfo
- type MetricName
- type MetricType
- type OvercommitFactor
- type ProjectMetadata
- type RateInfo
- type RateName
- type RateUsageReport
- type ResourceCapacityReport
- type ResourceDemand
- type ResourceDemandInAZ
- type ResourceInfo
- type ResourceName
- type ResourceQuotaRequest
- type ResourceTopologydeprecated
- type ResourceUsageReport
- type ServiceCapacityReport
- type ServiceCapacityRequest
- type ServiceInfo
- type ServiceQuotaRequest
- type ServiceUsageReport
- type ServiceUsageRequest
- type Subcapacity
- type SubcapacityBuilder
- type Subresource
- type SubresourceBuilder
- type Topology
- type Unit
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func InAnyAZ ¶
func InAnyAZ[T any](value T) map[AvailabilityZone]*T
InAnyAZ is a convenience constructor for the PerAZ fields of ResourceCapacityReport and ResourceUsageReport. It can be used for non-AZ-aware resources. The provided report will be placed under the AvailabilityZoneAny key.
func ValidateCapacityReport ¶ added in v1.14.3
func ValidateCapacityReport(report ServiceCapacityReport, req ServiceCapacityRequest, info ServiceInfo) error
ValidateCapacityReport checks that the provided report is consistent with the provided request and ServiceInfo. Currently, this means that:
- The report.InfoVersion must match the value in info.Version. (This is a hard error here. If the caller wants to be lenient about version mismatches, it may reload the ServiceInfo prior to validation.)
- All resources declared in info.Resources with HasCapacity = true must be present (and no others).
- Each resource must report exactly for those AZs that its declared topology requires: For FlatResourceTopology, only AvailabilityZoneAny is allowed. For other topologies, all AZs in req.AllAZs must be present (and possibly AvailabilityZoneUnknown, but no others).
- All metrics families declared in info.CapacityMetricFamilies must be present (and no others).
- The number of labels on each metric must match the declared label set.
Additional validations may be added in the future.
func ValidateServiceInfo ¶ added in v1.14.3
func ValidateServiceInfo(srv ServiceInfo) error
ValidateServiceInfo checks that the provided ServiceInfo is valid. Currently, this means that:
- Each resource is declared with a valid topology.
- Each rate is declared with a valid topology.
- Each rate is declared with HasUsage = true
Additional validations may be added in the future.
func ValidateUsageReport ¶ added in v1.14.3
func ValidateUsageReport(report ServiceUsageReport, req ServiceUsageRequest, info ServiceInfo) error
ValidateUsageReport checks that the provided report is consistent with the provided request and ServiceInfo. Currently, this means that:
- The report.InfoVersion must match the value in info.Version. (This is a hard error here. If the caller wants to be lenient about version mismatches, it may reload the ServiceInfo prior to validation.)
- All resources declared in info.Resources must be present (and no others).
- Each resource must report usage exactly for those AZs that its declared topology requires: For FlatResourceTopology, only AvailabilityZoneAny is allowed. For other topologies, all AZs in req.AllAZs must be present (and possibly AvailabilityZoneUnknown, but no others).
- All resources declared with HasQuota = true must report quota (and no others).
- Each resource reporting quota must report it in the way that its declared topology requires: For AZSeparatedResourceTopology, quota must be reported only on the AZ level, and only for real AZs (not for AvailabilityZoneUnknown). For all other topologies, quota must be reported only on the resource level.
- All rates declared in info.Rates must be present (and no others).
- Each rate must report usage exactly for those AZs that its declared topology requires: For FlatRateTopology, only AvailabilityZoneAny is allowed. For other topologies, all AZs in req.AllAZs must be present (and possibly AvailabilityZoneUnknown, but no others).
- For rate usage values, the value Some(nil) is forbidden.
- All metrics families declared in info.UsageMetricFamilies must be present (and no others).
- The number of labels on each metric must match the declared label set.
Additional validations may be added in the future.
Types ¶
type AZRateUsageReport ¶ added in v1.12.6
type AZRateUsageReport struct { // The amount of usage for this rate. Must be Some() and non-nil if the rate is declared with HasUsage = true. // The value Some(nil) is forbidden. // // For a given rate, project and AZ, this value must only ever increase monotonically over time. // If there is the possibility of counter resets or limited retention in the underlying data source, the liquid must add its own logic to guarantee monotonicity. // A common strategy is to remember previous measurements in the SerializedState field of type ServiceUsageReport. // // This field is modeled as a bigint because network rates like "bytes transferred" may easily exceed the range of uint64 over time. Usage Option[*big.Int] `json:"usage,omitzero"` }
AZRateUsageReport contains usage data for a rate in a single project and AZ. It appears in type RateUsageReport.
type AZResourceCapacityReport ¶
type AZResourceCapacityReport struct { // How much capacity is available to Limes in this resource and AZ. // // Caution: In some cases, underlying capacity can be used by multiple // resources. For example, the storage capacity in Manila pools can be used // by both the `share_capacity` and `snapshot_capacity` resources. In this case, // it is *incorrect* to just report the entire storage capacity in both resources. // Limes assumes that whatever number you provide here is free to be // allocated exclusively for the respective resource. If physical capacity // can be used by multiple resources, you need to split the capacity and // report only a chunk of the real capacity in each resource. // // If you need to split physical capacity between multiple resources like // this, the recommended way is to set "NeedsResourceDemand = true" and // then split capacity based on the demand reported by Limes. Capacity uint64 `json:"capacity"` // How much of the Capacity is used, or null if no usage data is available. // // This should only be reported if the service has an efficient way to obtain this number from the backend. // If you can only fill this by summing up usage across all projects, don't; Limes can already do that. // This is intended for consistency checks and to estimate how much usage cannot be attributed to OpenStack projects. // For example, for compute, this would allow estimating how many VMs are not managed by Nova. Usage Option[uint64] `json:"usage,omitzero"` // Only filled if the resource is able to report subcapacities in a useful way. Subcapacities []Subcapacity `json:"subcapacities,omitempty"` }
AZResourceCapacityReport contains capacity data for a resource in a single AZ. It appears in type ResourceCapacityReport.
type AZResourceQuotaRequest ¶ added in v1.13.0
type AZResourceQuotaRequest struct {
Quota uint64 `json:"quota"`
}
AZResourceQuotaRequest contains the new quota value for a single resource and AZ. It appears in type ResourceQuotaRequest.
type AZResourceUsageReport ¶
type AZResourceUsageReport struct { // The amount of usage for this resource. Usage uint64 `json:"usage"` // The amount of physical usage for this resource. // Only reported if this notion makes sense for the particular resource. // // For example, consider the Manila resource "share_capacity". // If a project has 5 shares, each with 10 GiB size and each containing 1 GiB data, then Usage = 50 GiB and PhysicalUsage = 5 GiB. // It is not allowed to report 5 GiB as Usage in this situation, since the 50 GiB value is used when judging whether the Quota fits. PhysicalUsage Option[uint64] `json:"physicalUsage,omitzero"` // This shall be non-null if and only if the resource is declared with AZSeparatedTopology. // A negative value, usually -1, indicates "infinite quota" (i.e., the absence of a quota). Quota Option[int64] `json:"quota,omitzero"` // Only filled if the resource is able to report subresources for this usage in a useful way. Subresources []Subresource `json:"subresources,omitempty"` }
AZResourceUsageReport contains usage data for a resource in a single project and AZ. It appears in type ResourceUsageReport.
func (AZResourceUsageReport) PrepareForBreakdownInto ¶
func (r AZResourceUsageReport) PrepareForBreakdownInto(allAZs []AvailabilityZone) map[AvailabilityZone]*AZResourceUsageReport
PrepareForBreakdownInto is a convenience constructor for the PerAZ field of ResourceUsageReport. It builds a map with zero-valued entries for all of the named AZs. Furthermore, if the provided AZ report contains nonzero usage, it is placed in the AvailabilityZoneUnknown key.
This constructor can be used when the total usage data is reported without AZ awareness. An AZ breakdown can later be added with the AddLocalizedUsage() method of ResourceUsageReport.
type AvailabilityZone ¶
type AvailabilityZone string
AvailabilityZone is the name of an availability zone. Some special values are enumerated below.
const ( // AvailabilityZoneAny marks values that are not bound to a specific AZ. AvailabilityZoneAny AvailabilityZone = "any" // AvailabilityZoneUnknown marks values that are bound to an unknown AZ. AvailabilityZoneUnknown AvailabilityZone = "unknown" )
func NormalizeAZ ¶ added in v1.13.2
func NormalizeAZ(rawAZ string, allAZs []AvailabilityZone) AvailabilityZone
NormalizeAZ takes an AZ name as reported by an OpenStack service and safely casts it into the AvailabilityZone type. If the provided raw value is not equal to any of the AZs known to Limes (from the second list), AvailabilityZoneUnknown will be returned.
type DomainMetadata ¶ added in v1.12.2
DomainMetadata includes metadata about a domain from Keystone.
It appears in type ProjectMetadata.
type Metric ¶
type Metric struct { Value float64 `json:"v"` // This label set does not include keys to avoid redundant encoding. // The slice must be of the same length as the LabelKeys slice in the respective MetricFamilyInfo instance in type ServiceInfo. // Each label value is implied to belong to the label key with the same slice index. // For example, LabelKeys = ["name","location"] and LabelValues = ["author","work"] represents the label set {name="author",location="work"}. LabelValues []string `json:"l"` }
Metric is a metric. This type appears in type ServiceCapacityReport. For more information, please refer to the "Metrics" section of the package documentation.
Because reports can include very large numbers of Metric instances, this type uses a compact serialization to improve efficiency.
type MetricFamilyInfo ¶
type MetricFamilyInfo struct { // The metric type. // The most common values are MetricTypeGauge and MetricTypeCounter. Type MetricType `json:"type"` // A brief description of the metric family for human consumption. // Should be short enough to be used as a tooltip. Help string `json:"help"` // All labels that will be present on each metric in this family. LabelKeys []string `json:"labelKeys"` }
MetricFamilyInfo describes a metric family. This type appears in type ServiceInfo. For more information, please refer to the "Metrics" section of the package documentation.
type MetricName ¶
type MetricName string
MetricName is the name of a metric family. For more information, please refer to the "Metrics" section of the package documentation.
type MetricType ¶
type MetricType string
MetricType is an enum. For more information, please refer to the "Metrics" section of the package documentation.
const ( MetricTypeUnknown MetricType = "unknown" MetricTypeGauge MetricType = "gauge" MetricTypeCounter MetricType = "counter" MetricTypeStateset MetricType = "stateset" MetricTypeInfo MetricType = "info" MetricTypeHistogram MetricType = "histogram" MetricTypeGaugeHistogram MetricType = "gaugehistogram" MetricTypeSummary MetricType = "summary" )
type OvercommitFactor ¶
type OvercommitFactor float64
OvercommitFactor is the ratio between raw and effective capacity of a resource. It appears in type ResourceDemand.
In its methods, the zero value behaves as 1, meaning that no overcommit is taking place.
func (OvercommitFactor) ApplyInReverseTo ¶
func (f OvercommitFactor) ApplyInReverseTo(capacity uint64) uint64
ApplyInReverseTo turns the given effective capacity back into a raw capacity.
func (OvercommitFactor) ApplyInReverseToDemand ¶
func (f OvercommitFactor) ApplyInReverseToDemand(demand ResourceDemandInAZ) ResourceDemandInAZ
ApplyInReverseToDemand is a shorthand for calling ApplyInReverseTo() on all fields of a ResourceDemand, thus turning all values initially given in terms of effective capacity into the corresponding raw capacity.
func (OvercommitFactor) ApplyTo ¶
func (f OvercommitFactor) ApplyTo(rawCapacity uint64) uint64
ApplyTo converts a raw capacity into an effective capacity.
type ProjectMetadata ¶ added in v1.12.2
type ProjectMetadata struct { UUID string `json:"uuid"` Name string `json:"name"` Domain DomainMetadata `json:"domain"` }
ProjectMetadata includes metadata about a project from Keystone.
It appears in types ServiceUsageRequest and ServiceQuotaRequest if requested by the ServiceInfo.
type RateInfo ¶ added in v1.12.6
type RateInfo struct { // If omitted or empty, the rate is "countable" and usage values describe a number of events. // If non-empty, the rate is "measured" and usage values are in multiples of the given unit. // For example, the storage rate "volume_creations" is countable, but the network rate "outbound_transfer" is measured, e.g. in bytes. Unit Unit `json:"unit,omitempty"` // How the rate reports usage. This field is required, and must contain one of the valid enum variants defined in this package. Topology Topology `json:"topology"` // Whether the liquid reports usage for this rate on the project level. // This must currently be true because there is no other reason for a rate to exist. // This requirement may be relaxed in the future, if LIQUID starts modelling rate limits and there are rates that have limits, but no usage tracking. HasUsage bool `json:"hasUsage"` }
RateInfo describes a rate that a liquid's service provides. This type appears in type ServiceInfo.
type RateName ¶ added in v1.12.6
type RateName string
RateName identifies a rate within a service. This type is used to distinguish rate names from other types of string values in function signatures.
type RateUsageReport ¶ added in v1.12.6
type RateUsageReport struct { // The keys that are allowed in this map depend on the chosen Topology. // See documentation on Topology enum variants for details. PerAZ map[AvailabilityZone]*AZRateUsageReport `json:"perAZ"` }
RateUsageReport contains usage data for a rate in a single project. It appears in type ServiceUsageReport.
type ResourceCapacityReport ¶
type ResourceCapacityReport struct { // The keys that are allowed in this map depend on the chosen Topology. // See documentation on Topology enum variants for details. PerAZ map[AvailabilityZone]*AZResourceCapacityReport `json:"perAZ"` }
ResourceCapacityReport contains capacity data for a resource. It appears in type ServiceCapacityReport.
type ResourceDemand ¶
type ResourceDemand struct { // Demand values are provided in terms of effective capacity. // This factor can be applied to them in reverse to obtain values in terms of raw capacity. OvercommitFactor OvercommitFactor `json:"overcommitFactor,omitempty"` // The actual demand values are AZ-aware. // The keys that can be expected in this map depend on the chosen Topology. PerAZ map[AvailabilityZone]ResourceDemandInAZ `json:"perAZ"` }
ResourceDemand contains demand statistics for a resource. It appears in type ServiceCapacityRequest.
This is used when a liquid needs to be able to reshuffle capacity between different resources based on actual user demand.
type ResourceDemandInAZ ¶
type ResourceDemandInAZ struct { // Usage counts all existing usage. Usage uint64 `json:"usage"` // UnusedCommitments counts all commitments that are confirmed but not covered by existing usage. UnusedCommitments uint64 `json:"unusedCommitments"` // PendingCommitments counts all commitments that should be confirmed by now, but are not. PendingCommitments uint64 `json:"pendingCommitments"` }
ResourceDemandInAZ contains demand statistics for a resource in a single AZ. It appears in type ResourceDemand.
The fields are ordered in descending priority. All values are in terms of effective capacity, and are sums over all OpenStack projects.
type ResourceInfo ¶
type ResourceInfo struct { // If omitted or empty, the resource is "countable" and any quota or usage values describe a number of objects. // If non-empty, the resource is "measured" and quota or usage values are in multiples of the given unit. // For example, the compute resource "cores" is countable, but the compute resource "ram" is measured, usually in MiB. Unit Unit `json:"unit,omitempty"` // How the resource reports usage (and capacity, if any). This field is required, and must contain one of the valid enum variants defined in this package. Topology Topology `json:"topology"` // Whether the liquid reports capacity for this resource on the cluster level. HasCapacity bool `json:"hasCapacity"` // Whether Limes needs to include demand statistics for this resource in its requests for a capacity report. NeedsResourceDemand bool `json:"needsResourceDemand"` // Whether the liquid reports quota for this resource on the project level. // If false, only usage is reported on the project level. // Limes will abstain from maintaining quota on such resources. HasQuota bool `json:"hasQuota"` // Additional resource-specific attributes. // For example, a resource for baremetal nodes of a certain flavor might report flavor attributes like the CPU and RAM size here, instead of on subcapacities and subresources, to avoid repetition. // // This must be shaped like a map[string]any, but is typed as a raw JSON message. // Limes does not touch these attributes and will just pass them on into its users without deserializing it at all. Attributes json.RawMessage `json:"attributes,omitempty"` }
ResourceInfo describes a resource that a liquid's service provides. This type appears in type ServiceInfo.
type ResourceName ¶
type ResourceName string
ResourceName identifies a resource within a service. This type is used to distinguish resource names from other types of string values in function signatures.
type ResourceQuotaRequest ¶
type ResourceQuotaRequest struct { // For FlatTopology and AZAwareTopology, this is the only field that is filled, and PerAZ will be nil. // For AZSeparatedTopology, this contains the sum of the quotas across all AZs (for compatibility purposes). Quota uint64 `json:"quota"` // PerAZ will only be filled for AZSeparatedTopology. PerAZ map[AvailabilityZone]AZResourceQuotaRequest `json:"perAZ,omitempty"` }
ResourceQuotaRequest contains new quotas for a single resource. It appears in type ServiceQuotaRequest.
type ResourceTopology
deprecated
added in
v1.13.0
type ResourceTopology = Topology
ResourceTopology is a synonym for Topology.
Deprecated: Use Topology instead.
const ( // Deprecated: Use FlatTopology instead. FlatResourceTopology ResourceTopology = FlatTopology // Deprecated: Use AZAwareTopology instead. AZAwareResourceTopology ResourceTopology = AZAwareTopology // Deprecated: Use AZSeparatedTopology instead. AZSeparatedResourceTopology ResourceTopology = AZSeparatedTopology )
type ResourceUsageReport ¶
type ResourceUsageReport struct { // If true, this project is forbidden from accessing this resource. // This has two consequences: // - If the resource has quota, Limes will never try to assign quota for this resource to this project except to cover existing usage. // - If the project has no usage in this resource, Limes will hide this resource from project reports. Forbidden bool `json:"forbidden"` // This shall be None if and only if the resource is declared with "HasQuota = false" or with AZSeparatedTopology. // A negative value, usually -1, indicates "infinite quota" (i.e., the absence of a quota). Quota Option[int64] `json:"quota,omitzero"` // The keys that are allowed in this map depend on the chosen Topology. // See documentation on Topology enum variants for details. // // Tip: When filling this by starting from a non-AZ-aware usage number that is later broken down with AZ-aware data, use func PrepareForBreakdownInto. PerAZ map[AvailabilityZone]*AZResourceUsageReport `json:"perAZ"` }
ResourceUsageReport contains usage data for a resource in a single project. It appears in type ServiceUsageReport.
func (*ResourceUsageReport) AddLocalizedUsage ¶
func (r *ResourceUsageReport) AddLocalizedUsage(az AvailabilityZone, usage uint64)
AddLocalizedUsage subtracts the given `usage from AvailabilityZoneUnknown (if any) and adds it to the given AZ instead.
This is used when breaking down a usage total reported by a non-AZ-aware API by iterating over AZ-localized objects. The hope is that the sum of usage of the AZ-localized objects matches the reported usage total. If this is the case, the entry for AvailabilityZoneUnknown will be removed entirely once it reaches zero usage.
type ServiceCapacityReport ¶
type ServiceCapacityReport struct { // The same version number that is reported in the Version field of a GET /v1/info response. // This is used to signal to Limes to refetch GET /v1/info after configuration changes. InfoVersion int64 `json:"infoVersion"` // Must contain an entry for each resource that was declared in type ServiceInfo with "HasCapacity = true". Resources map[ResourceName]*ResourceCapacityReport `json:"resources,omitempty"` // Must contain an entry for each metric family that was declared for capacity metrics in type ServiceInfo. Metrics map[MetricName][]Metric `json:"metrics,omitempty"` }
ServiceCapacityReport is the response payload format for POST /v1/report-capacity.
type ServiceCapacityRequest ¶
type ServiceCapacityRequest struct { // All AZs known to Limes. // Many liquids need this information to ensure that: // - AZ-aware capacity is reported for all known AZs, and // - capacity belonging to an invalid AZ is grouped into AvailabilityZoneUnknown. // Limes provides this list here to reduce the number of places where this information needs to be maintained manually. AllAZs []AvailabilityZone `json:"allAZs"` // Must contain an entry for each resource that was declared in type ServiceInfo with "NeedsResourceDemand = true". DemandByResource map[ResourceName]ResourceDemand `json:"demandByResource"` }
ServiceCapacityRequest is the request payload format for POST /v1/report-capacity.
type ServiceInfo ¶
type ServiceInfo struct { // This version number shall be increased whenever any part of the ServiceInfo changes. // // The metadata version is also reported on most other API responses. // Limes uses this version number to discover when the metadata has changed and needs to be queried again. // // There is no prescribed semantics to the value of the version number, except that: // - Changes in ServiceInfo must lead to a monotonic increase of the Version. // - If the contents of ServiceInfo do not change, the Version too shall not change. // // Our recommendation is to use the UNIX timestamp of the most recent change. // If you run multiple replicas of the liquid, take care to ensure that they agree on the Version value. Version int64 `json:"version"` // Info for each resource that this service provides. Resources map[ResourceName]ResourceInfo `json:"resources"` // Info for each rate that this service provides. Rates map[RateName]RateInfo `json:"rates"` // Info for each metric family that is included in a response to a query for cluster capacity. CapacityMetricFamilies map[MetricName]MetricFamilyInfo `json:"capacityMetricFamilies"` // Info for each metric family that is included in a response to a query for project quota and usage. UsageMetricFamilies map[MetricName]MetricFamilyInfo `json:"usageMetricFamilies"` // Whether Limes needs to include the ProjectMetadata field in its requests for usage reports. UsageReportNeedsProjectMetadata bool `json:"usageReportNeedsProjectMetadata,omitempty"` // Whether Limes needs to include the ProjectMetadata field in its quota update requests. QuotaUpdateNeedsProjectMetadata bool `json:"quotaUpdateNeedsProjectMetadata,omitempty"` }
ServiceInfo is the response payload format for GET /v1/info.
type ServiceQuotaRequest ¶
type ServiceQuotaRequest struct { Resources map[ResourceName]ResourceQuotaRequest `json:"resources"` // Metadata about the project from Keystone. // Only included if the ServiceInfo declared a need for it. ProjectMetadata Option[ProjectMetadata] `json:"projectMetadata,omitzero"` }
ServiceQuotaRequest is the request payload format for PUT /v1/projects/:uuid/quota.
type ServiceUsageReport ¶
type ServiceUsageReport struct { // The same version number that is reported in the Version field of a GET /v1/info response. // This is used to signal to Limes to refetch GET /v1/info after configuration changes. InfoVersion int64 `json:"infoVersion"` // Must contain an entry for each resource that was declared in type ServiceInfo. Resources map[ResourceName]*ResourceUsageReport `json:"resources,omitempty"` // Must contain an entry for each rate that was declared in type ServiceInfo. Rates map[RateName]*RateUsageReport `json:"rates,omitempty"` // Must contain an entry for each metric family that was declared for usage metrics in type ServiceInfo. Metrics map[MetricName][]Metric `json:"metrics,omitempty"` // Opaque state for Limes to persist and return to the liquid in the next ServiceUsageRequest for the same project. // This should only be used if the liquid needs to store project-level data, but does not have its own database. // // This field is intended specifically for rate usage measurements, esp. to detect and handle counter resets in the backend. // In this case, it might contain information like "counter C had value V at time T". // // Warning: As of the time of this writing, Limes may not loop this field back consistently if the liquid has resources. // This behavior is considered a bug and will be fixed eventually. SerializedState json.RawMessage `json:"serializedState,omitempty"` }
ServiceUsageReport is the response payload format for POST /v1/projects/:uuid/report-usage.
type ServiceUsageRequest ¶
type ServiceUsageRequest struct { // All AZs known to Limes. // Many liquids need this information to ensure that: // - AZ-aware usage is reported for all known AZs, and // - usage belonging to an invalid AZ is grouped into AvailabilityZoneUnknown. // Limes provides this list here to reduce the number of places where this information needs to be maintained manually. AllAZs []AvailabilityZone `json:"allAZs"` // Metadata about the project from Keystone. // Only included if the ServiceInfo declared a need for it. ProjectMetadata Option[ProjectMetadata] `json:"projectMetadata,omitzero"` // The serialized state from the previous ServiceUsageReport received by Limes for this project, if any. // Refer to the same field on type ServiceUsageReport for details. SerializedState json.RawMessage `json:"serializedState,omitempty"` }
ServiceUsageRequest is the request payload format for POST /v1/projects/:uuid/report-usage.
type Subcapacity ¶
type Subcapacity struct { // A machine-readable unique identifier for this subcapacity, if there is one. ID string `json:"id,omitempty"` // A human-readable unique identifier for this subcapacity, if there is one. Name string `json:"name,omitempty"` // The amount of capacity in this subcapacity. Capacity uint64 `json:"capacity"` // How much of the Capacity is used, or None if no usage data is available. Usage Option[uint64] `json:"usage,omitzero"` // Additional resource-specific attributes. // This must be shaped like a map[string]any, but is typed as a raw JSON message. // Limes does not touch these attributes and will just pass them on into its users without deserializing it at all. Attributes json.RawMessage `json:"attributes,omitempty"` }
Subcapacity describes a distinct chunk of capacity for a resource within an AZ. It appears in type AZResourceCapacityReport.
A service will only report subcapacities for such resources where there is a useful substructure to report. For example:
- Nova can report its hypervisors as subcapacities of the "cores" and "ram" resources.
- Cinder can report its storage pools as subcapacities of the "capacity" resource.
The required fields are "Capacity" and at least one of "ID" or "Name".
There is no guarantee that the Capacity values of all subcapacities sum up to the total capacity of the resource. For example, some subcapacities may be excluded from new provisioning. The capacity calculation could then take this into account and exclude unused capacity from the total.
type SubcapacityBuilder ¶
type SubcapacityBuilder[A any] struct { ID string Name string Capacity uint64 Usage Option[uint64] Attributes A }
SubcapacityBuilder is a helper type for building Subcapacity values. If the Attributes in a subcapacity are collected over time, it might be more convenient to have them accessible as a structured type. Once assembly is complete, the provided methods can be used to obtain the final Subcapacity value.
func (SubcapacityBuilder[A]) Finalize ¶
func (b SubcapacityBuilder[A]) Finalize() (Subcapacity, error)
Finalize converts this SubcapacityBuilder into a Subcapacity by serializing the Attributes field to JSON. If an error is returned, it is from the json.Marshal() step.
type Subresource ¶
type Subresource struct { // A machine-readable unique identifier for this subresource, if there is one. ID string `json:"id,omitempty"` // A human-readable identifier for this subresource, if there is one. // Must be unique at least within its project. Name string `json:"name,omitempty"` // Must be None for counted resources (for which each subresource must be one of the things that is counted). // Must be Some for measured resources, and contain the subresource's size in terms of the resource's unit. Usage Option[uint64] `json:"usage,omitzero"` // Additional resource-specific attributes. // This must be shaped like a map[string]any, but is typed as a raw JSON message. // Limes does not touch these attributes and will just pass them on into its users without deserializing it at all. Attributes json.RawMessage `json:"attributes,omitempty"` }
Subresource describes a distinct chunk of usage for a resource within a project and AZ. It appears in type AZResourceUsageReport.
A service will only report subresources for such resources where there is a useful substructure to report. For example, in the Nova resource "instances", each instance is a subresource.
The required fields are "Size" (only for measured resources) and at least one of "ID" or "Name".
type SubresourceBuilder ¶
SubresourceBuilder is a helper type for building Subresource values. If the Attributes in a subresource are collected over time, it might be more convenient to have them accessible as a structured type. Once assembly is complete, the provided methods can be used to obtain the final Subresource value.
func (SubresourceBuilder[A]) Finalize ¶
func (b SubresourceBuilder[A]) Finalize() (Subresource, error)
Finalize converts this SubresourceBuilder into a Subresource by serializing the Attributes field to JSON. If an error is returned, it is from the json.Marshal() step.
type Topology ¶ added in v1.14.1
type Topology string
Topology describes how capacity and usage reported by a certain resource is structured. Type type appears in type ResourceInfo.
const ( // FlatTopology is a topology for resources that are not AZ-aware at all. // In reports for this resource, PerAZ must contain exactly one key: AvailabilityZoneAny. // Any other entry, as well as the absence of AvailabilityZoneAny, will be considered an error by Limes. // // If the resource sets HasQuota = true, only a flat number will be given, and PerAZ will be null. FlatTopology Topology = "flat" // AZAwareTopology is a topology for resources that can measure capacity and usage by AZ. // In reports for this resource, PerAZ shall contain an entry for each AZ mentioned in the AllAZs key of the request. // PerAZ may also include an entry for AvailabilityZoneUnknown as needed. // Any other entry (including AvailabilityZoneAny) will be considered an error by Limes. // // If the resource sets "HasQuota = true", only a flat number will be given, and PerAZ will be null. // This behavior matches the AZ-unawareness of quota in most OpenStack services. AZAwareTopology Topology = "az-aware" // AZSeparatedTopology is like AZAwareTopology, but quota is also AZ-aware. // For resources with HasQuota = false, this behaves the same as AZAwareTopology. // // If the resource sets "HasQuota = true", quota requests will include the PerAZ breakdown. // PerAZ will only contain quotas for actual AZs, not for AvailabilityZoneAny or AvailabilityZoneUnknown. AZSeparatedTopology Topology = "az-separated" )
type Unit ¶
type Unit string
Unit enumerates allowed values for the unit a resource's quota/usage is measured in.
const ( // UnitNone is used for countable (rather than measurable) resources. UnitNone Unit = "" // UnitBytes is exactly that. UnitBytes Unit = "B" // UnitKibibytes is exactly that. UnitKibibytes Unit = "KiB" // UnitMebibytes is exactly that. UnitMebibytes Unit = "MiB" // UnitGibibytes is exactly that. UnitGibibytes Unit = "GiB" // UnitTebibytes is exactly that. UnitTebibytes Unit = "TiB" // UnitPebibytes is exactly that. UnitPebibytes Unit = "PiB" // UnitExbibytes is exactly that. UnitExbibytes Unit = "EiB" // UnitUnspecified is used as a placeholder when the unit is not known. UnitUnspecified Unit = "UNSPECIFIED" )
func (Unit) Base ¶
Base returns the base unit of this unit. For units defined as a multiple of another unit, that unit is the base unit. Otherwise, the same unit and a multiple of 1 is returned.
func (*Unit) UnmarshalJSON ¶
UnmarshalJSON implements the json.Unmarshaler interface. This method validates that the named unit actually exists.
func (*Unit) UnmarshalYAML
deprecated
UnmarshalYAML implements the yaml.Unmarshaler interface. This method validates that the named unit actually exists.
Deprecated: This provides backwards-compatibility with existing YAML-based config file formats in Limes which will be replaced by JSON eventually.