Documentation
¶
Index ¶
- Constants
- Variables
- func CheckCommitmentsInfoEndpoint(ctx context.Context, config E2EChecksConfig)
- func FlavorGroupAcceptsCommitments(fg *compute.FlavorGroupFeature) bool
- func FlavorGroupCommitmentRejectionReason(fg *compute.FlavorGroupFeature) string
- func GetMaxSlotIndex(reservations []v1alpha1.Reservation) int
- func GetNextSlotIndex(reservations []v1alpha1.Reservation) int
- func LoggerFromContext(ctx context.Context) logr.Logger
- func ResourceNameCores(flavorGroup string) string
- func ResourceNameInstances(flavorGroup string) string
- func ResourceNameRAM(flavorGroup string) string
- func RunCommitmentsE2EChecks(ctx context.Context, config E2EChecksConfig)
- func WithGlobalRequestID(ctx context.Context, greq string) context.Context
- func WithNewGlobalRequestID(ctx context.Context) context.Context
- type ApplyResult
- type CapacityCalculator
- type ChangeCommitmentsAPIMonitor
- type Commitment
- type CommitmentReservationController
- func (r *CommitmentReservationController) Init(ctx context.Context, client client.Client, conf Config) error
- func (r *CommitmentReservationController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)
- func (r *CommitmentReservationController) SetupWithManager(mgr ctrl.Manager, mcl *multicluster.Client) error
- type CommitmentState
- func FromChangeCommitmentTargetState(commitment liquid.Commitment, projectID string, flavorGroupName string, ...) (*CommitmentState, error)
- func FromCommitment(commitment Commitment, flavorGroup compute.FlavorGroupFeature) (*CommitmentState, error)
- func FromReservations(reservations []v1alpha1.Reservation) (*CommitmentState, error)
- type CommitmentStateWithUsage
- type CommitmentsClient
- type Config
- type E2EChecksConfig
- type Flavor
- type HTTPAPI
- func (api *HTTPAPI) HandleChangeCommitments(w http.ResponseWriter, r *http.Request)
- func (api *HTTPAPI) HandleInfo(w http.ResponseWriter, r *http.Request)
- func (api *HTTPAPI) HandleQuota(w http.ResponseWriter, r *http.Request)
- func (api *HTTPAPI) HandleReportCapacity(w http.ResponseWriter, r *http.Request)
- func (api *HTTPAPI) HandleReportUsage(w http.ResponseWriter, r *http.Request)
- func (api *HTTPAPI) Init(mux *http.ServeMux, registry prometheus.Registerer, log logr.Logger)
- type InfoAPIMonitor
- type Project
- type ReportCapacityAPIMonitor
- type ReportUsageAPIMonitor
- type ReservationManager
- type Server
- type Syncer
- type SyncerConfig
- type SyncerMonitor
- func (m *SyncerMonitor) Collect(ch chan<- prometheus.Metric)
- func (m *SyncerMonitor) Describe(ch chan<- *prometheus.Desc)
- func (m *SyncerMonitor) RecordCommitmentProcessed()
- func (m *SyncerMonitor) RecordCommitmentSeen()
- func (m *SyncerMonitor) RecordCommitmentSkipped(reason string)
- func (m *SyncerMonitor) RecordReservationsCreated(count int)
- func (m *SyncerMonitor) RecordReservationsDeleted(count int)
- func (m *SyncerMonitor) RecordReservationsRepaired(count int)
- func (m *SyncerMonitor) RecordSyncError()
- func (m *SyncerMonitor) RecordSyncRun()
- func (m *SyncerMonitor) RecordUnitMismatch(_ string)
- type UsageCalculator
- type UsageNovaClient
- type VMUsageInfo
Constants ¶
const ( // Resource type suffixes ResourceSuffixRAM = "_ram" ResourceSuffixCores = "_cores" ResourceSuffixInstances = "_instances" )
Limes LIQUID resource naming convention: hw_version_<flavorgroup>_<resourcetype> Supported resource types: _ram, _cores, _instances
const ( SkipReasonUnitMismatch = "unit_mismatch" SkipReasonUnknownFlavorGroup = "unknown_flavor_group" SkipReasonInvalidResource = "invalid_resource_name" SkipReasonEmptyUUID = "empty_uuid" SkipReasonNonCompute = "non_compute" )
Skip reason labels for commitment processing
Variables ¶
var (
// CreatorValue identifies reservations created by this syncer.
CreatorValue = "commitments-syncer"
)
Functions ¶
func CheckCommitmentsInfoEndpoint ¶
func CheckCommitmentsInfoEndpoint(ctx context.Context, config E2EChecksConfig)
CheckCommitmentsInfoEndpoint sends a GET request to the /commitments/v1/info endpoint and verifies that it returns HTTP 200 with a valid ServiceInfo response.
func FlavorGroupAcceptsCommitments ¶
func FlavorGroupAcceptsCommitments(fg *compute.FlavorGroupFeature) bool
FlavorGroupAcceptsCommitments returns true if the given flavor group can accept committed resources. Currently, only groups with a fixed RAM/core ratio (all flavors have the same ratio) accept CRs. This is the single source of truth for CR eligibility and should be used across all CR APIs.
func FlavorGroupCommitmentRejectionReason ¶
func FlavorGroupCommitmentRejectionReason(fg *compute.FlavorGroupFeature) string
FlavorGroupCommitmentRejectionReason returns the reason why the given flavor group does not accept CRs. Returns empty string if the group accepts commitments.
func GetMaxSlotIndex ¶
func GetMaxSlotIndex(reservations []v1alpha1.Reservation) int
func GetNextSlotIndex ¶
func GetNextSlotIndex(reservations []v1alpha1.Reservation) int
Always continue counting slots from max, instead of filling gaps.
func LoggerFromContext ¶
LoggerFromContext returns a logger with greq and req values from the context. This creates a child logger with the request tracking values pre-attached, so you don't need to repeat them in every log call.
func ResourceNameCores ¶
ResourceNameCores creates a LIQUID resource name for CPU cores from a flavor group name. Format: hw_version_<flavorgroup>_cores
func ResourceNameInstances ¶
ResourceNameInstances creates a LIQUID resource name for instance count from a flavor group name. Format: hw_version_<flavorgroup>_instances
func ResourceNameRAM ¶
ResourceNameRAM creates a LIQUID resource name for RAM from a flavor group name. Format: hw_version_<flavorgroup>_ram
func RunCommitmentsE2EChecks ¶
func RunCommitmentsE2EChecks(ctx context.Context, config E2EChecksConfig)
RunCommitmentsE2EChecks runs all e2e checks for the commitments API.
func WithGlobalRequestID ¶
WithGlobalRequestID creates a new context with the specified global request ID. This is used to propagate existing request IDs (e.g., from the creator annotation).
Types ¶
type ApplyResult ¶
type ApplyResult struct {
// Created is the number of reservations created
Created int
// Deleted is the number of reservations deleted
Deleted int
// Repaired is the number of reservations repaired (metadata sync or recreated due to wrong config)
Repaired int
// TouchedReservations are reservations that were created or updated
TouchedReservations []v1alpha1.Reservation
// RemovedReservations are reservations that were deleted
RemovedReservations []v1alpha1.Reservation
}
ApplyResult contains the result of applying a commitment state.
type CapacityCalculator ¶
type CapacityCalculator struct {
// contains filtered or unexported fields
}
CapacityCalculator computes capacity reports for Limes LIQUID API.
func NewCapacityCalculator ¶
func NewCapacityCalculator(client client.Client) *CapacityCalculator
func (*CapacityCalculator) CalculateCapacity ¶
func (c *CapacityCalculator) CalculateCapacity(ctx context.Context, req liquid.ServiceCapacityRequest) (liquid.ServiceCapacityReport, error)
CalculateCapacity computes per-AZ capacity for all flavor groups. For each flavor group, three resources are reported: _ram, _cores, _instances. All flavor groups are included, not just those with fixed RAM/core ratio. The request provides the list of all AZs from Limes that must be included in the report.
type ChangeCommitmentsAPIMonitor ¶
type ChangeCommitmentsAPIMonitor struct {
// contains filtered or unexported fields
}
ChangeCommitmentsAPIMonitor provides metrics for the CR change API.
func NewChangeCommitmentsAPIMonitor ¶
func NewChangeCommitmentsAPIMonitor() ChangeCommitmentsAPIMonitor
NewChangeCommitmentsAPIMonitor creates a new monitor with Prometheus metrics. Metrics are pre-initialized with zero values for common HTTP status codes to ensure they appear in Prometheus before the first request.
func (*ChangeCommitmentsAPIMonitor) Collect ¶
func (m *ChangeCommitmentsAPIMonitor) Collect(ch chan<- prometheus.Metric)
Collect implements prometheus.Collector.
func (*ChangeCommitmentsAPIMonitor) Describe ¶
func (m *ChangeCommitmentsAPIMonitor) Describe(ch chan<- *prometheus.Desc)
Describe implements prometheus.Collector.
type Commitment ¶
type Commitment struct {
// A unique numerical identifier for this commitment. This API uses this
// numerical ID to refer to the commitment in other API calls.
ID int `json:"id"`
// A unique string identifier for this commitment. The next major version of
// this API will use this UUID instead of the numerical ID to refer to
// commitments in API calls.
UUID string `json:"uuid"`
// The resource for which usage is committed.
ServiceType string `json:"service_type"`
ResourceName string `json:"resource_name"`
// The availability zone in which usage is committed.
AvailabilityZone string `json:"availability_zone"`
// The amount of usage that was committed to.
Amount uint64 `json:"amount"`
// For measured resources, the unit for this resource. The value from the
// amount field is measured in this unit.
Unit string `json:"unit"`
// The requested duration of this commitment, expressed as a comma-separated
// sequence of positive integer multiples of time units like "1 year,
// 3 months". Acceptable time units include "second", "minute", "hour",
// "day", "month" and "year".
Duration string `json:"duration"`
// UNIX timestamp when this commitment was created.
CreatedAt uint64 `json:"created_at"`
// UNIX timestamp when this commitment should be confirmed. Only shown if
// this was given when creating the commitment, to delay confirmation into
// the future.
ConfirmBy *uint64 `json:"confirm_by,omitempty"`
// UNIX timestamp when this commitment was confirmed. Only shown after
// confirmation.
ConfirmedAt *uint64 `json:"confirmed_at,omitempty"`
// UNIX timestamp when this commitment is set to expire. Note that the
// duration counts from confirmBy (or from createdAt for immediately-
// confirmed commitments) and is calculated at creation time, so this is
// also shown on unconfirmed commitments.
ExpiresAt uint64 `json:"expires_at"`
// Whether the commitment is marked for transfer to a different project.
// Transferable commitments do not count towards quota calculation in their
// project, but still block capacity and still count towards billing. Not
// shown if false.
Transferable bool `json:"transferable"`
// The current status of this commitment. If provided, one of "planned",
// "pending", "guaranteed", "confirmed", "superseded", or "expired".
Status string `json:"status,omitempty"`
// Whether a mail notification should be sent if a created commitment is
// confirmed. Can only be set if the commitment contains a confirmBy value.
NotifyOnConfirm bool `json:"notify_on_confirm"`
// The openstack project ID this commitment is for.
ProjectID string `json:"project_id"`
// The openstack domain ID this commitment is for.
DomainID string `json:"domain_id"`
}
Commitment model from the limes API. See: https://github.com/sapcc/limes/blob/5ea068b/docs/users/api-spec-resources.md?plain=1#L493 See: https://github.com/sapcc/go-api-declarations/blob/94ee3e5/limes/resources/commitment.go#L19
type CommitmentReservationController ¶
type CommitmentReservationController struct {
// Client for the kubernetes API.
client.Client
// Kubernetes scheme to use for the reservations.
Scheme *runtime.Scheme
// Configuration for the controller.
Conf Config
// Database connection for querying VM state from Knowledge cache.
DB *db.DB
// SchedulerClient for making scheduler API calls.
SchedulerClient *reservations.SchedulerClient
}
CommitmentReservationController reconciles commitment Reservation objects
func (*CommitmentReservationController) Init ¶
func (r *CommitmentReservationController) Init(ctx context.Context, client client.Client, conf Config) error
Init initializes the reconciler with required clients and DB connection.
func (*CommitmentReservationController) Reconcile ¶
func (r *CommitmentReservationController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)
Reconcile is part of the main kubernetes reconciliation loop which aims to move the current state of the cluster closer to the desired state. Note: This controller only handles commitment reservations, as filtered by the predicate.
func (*CommitmentReservationController) SetupWithManager ¶
func (r *CommitmentReservationController) SetupWithManager(mgr ctrl.Manager, mcl *multicluster.Client) error
SetupWithManager sets up the controller with the Manager.
type CommitmentState ¶
type CommitmentState struct {
// CommitmentUUID is the UUID of the commitment this state corresponds to.
CommitmentUUID string
// ProjectID is the OpenStack project this commitment belongs to
ProjectID string
// DomainID is the OpenStack domain this commitment belongs to
DomainID string
// FlavorGroupName identifies the flavor group (e.g., "hana_medium_v2")
FlavorGroupName string
// the total memory in bytes across all reservation slots
TotalMemoryBytes int64
// AvailabilityZone specifies the availability zone for this commitment
AvailabilityZone string
// StartTime is when the commitment becomes active
StartTime *time.Time
// EndTime is when the commitment expires
EndTime *time.Time
// CreatorRequestID is the request ID that triggered this state change (for traceability)
CreatorRequestID string
}
CommitmentState represents desired or current commitment resource allocation.
func FromChangeCommitmentTargetState ¶
func FromChangeCommitmentTargetState( commitment liquid.Commitment, projectID string, flavorGroupName string, flavorGroup compute.FlavorGroupFeature, az string, ) (*CommitmentState, error)
FromChangeCommitmentTargetState converts LIQUID API request to CommitmentState.
func FromCommitment ¶
func FromCommitment( commitment Commitment, flavorGroup compute.FlavorGroupFeature, ) (*CommitmentState, error)
FromCommitment converts Limes commitment to CommitmentState.
func FromReservations ¶
func FromReservations(reservations []v1alpha1.Reservation) (*CommitmentState, error)
FromReservations reconstructs CommitmentState from existing Reservation CRDs.
type CommitmentStateWithUsage ¶
type CommitmentStateWithUsage struct {
CommitmentState
// RemainingMemoryBytes is the uncommitted capacity left for VM assignment
RemainingMemoryBytes int64
// AssignedVMs tracks which VMs have been assigned to this commitment
AssignedVMs []string
}
CommitmentStateWithUsage extends CommitmentState with usage tracking for billing calculations. Used by the report-usage API to track remaining capacity during VM-to-commitment assignment.
func NewCommitmentStateWithUsage ¶
func NewCommitmentStateWithUsage(state *CommitmentState) *CommitmentStateWithUsage
NewCommitmentStateWithUsage creates a CommitmentStateWithUsage from a CommitmentState.
func (*CommitmentStateWithUsage) AssignVM ¶
func (c *CommitmentStateWithUsage) AssignVM(vmUUID string, vmMemoryBytes int64) bool
AssignVM attempts to assign a VM to this commitment if there's enough capacity. Returns true if the VM was assigned, false if not enough capacity.
func (*CommitmentStateWithUsage) HasRemainingCapacity ¶
func (c *CommitmentStateWithUsage) HasRemainingCapacity() bool
HasRemainingCapacity returns true if the commitment has any remaining capacity.
type CommitmentsClient ¶
type CommitmentsClient interface {
// Init the client.
Init(ctx context.Context, client client.Client, conf SyncerConfig) error
// List all projects to resolve commitments.
ListProjects(ctx context.Context) ([]Project, error)
// List all commitments with resolved metadata (e.g. project, flavor, ...).
ListCommitmentsByID(ctx context.Context, projects ...Project) (map[string]Commitment, error)
}
Client to fetch commitments.
func NewCommitmentsClient ¶
func NewCommitmentsClient() CommitmentsClient
type Config ¶
type Config struct {
// RequeueIntervalActive is the interval for requeueing active reservations for verification.
RequeueIntervalActive time.Duration `json:"committedResourceRequeueIntervalActive"`
// RequeueIntervalRetry is the interval for requeueing when retrying after knowledge is not ready.
RequeueIntervalRetry time.Duration `json:"committedResourceRequeueIntervalRetry"`
// PipelineDefault is the default pipeline used for scheduling committed resource reservations.
PipelineDefault string `json:"committedResourcePipelineDefault"`
// SchedulerURL is the endpoint of the nova external scheduler
SchedulerURL string `json:"schedulerURL"`
// Secret ref to SSO credentials stored in a k8s secret, if applicable.
SSOSecretRef *corev1.SecretReference `json:"ssoSecretRef"`
// Secret ref to keystone credentials stored in a k8s secret.
KeystoneSecretRef corev1.SecretReference `json:"keystoneSecretRef"`
// Secret ref to the database credentials for querying VM state.
DatabaseSecretRef *corev1.SecretReference `json:"databaseSecretRef,omitempty"`
// FlavorGroupPipelines maps flavor group names to pipeline names.
// Example: {"2152": "kvm-hana-bin-packing", "2101": "kvm-general-purpose-load-balancing", "*": "kvm-general-purpose-load-balancing"}
// Used to select different scheduling pipelines based on flavor group characteristics.
FlavorGroupPipelines map[string]string `json:"committedResourceFlavorGroupPipelines,omitempty"`
// ChangeAPIWatchReservationsTimeout defines how long to wait for reservations to become ready before timing out and rolling back.
ChangeAPIWatchReservationsTimeout time.Duration `json:"committedResourceChangeAPIWatchReservationsTimeout"`
// ChangeAPIWatchReservationsPollInterval defines how frequently to poll reservation status during watch.
ChangeAPIWatchReservationsPollInterval time.Duration `json:"committedResourceChangeAPIWatchReservationsPollInterval"`
// EnableChangeCommitmentsAPI controls whether the change-commitments API endpoint is active.
// When false, the endpoint will return HTTP 503 Service Unavailable.
// The info endpoint remains available for health checks.
EnableChangeCommitmentsAPI bool `json:"committedResourceEnableChangeCommitmentsAPI"`
// EnableReportUsageAPI controls whether the report-usage API endpoint is active.
// When false, the endpoint will return HTTP 503 Service Unavailable.
// This can be used as an emergency switch if the usage reporting is causing issues.
EnableReportUsageAPI bool `json:"committedResourceEnableReportUsageAPI"`
// EnableReportCapacityAPI controls whether the report-capacity API endpoint is active.
// When false, the endpoint will return HTTP 503 Service Unavailable.
// This can be used as an emergency switch if the capacity reporting is causing issues.
EnableReportCapacityAPI bool `json:"committedResourceEnableReportCapacityAPI"`
}
func DefaultConfig ¶
func DefaultConfig() Config
func (*Config) ApplyDefaults ¶
func (c *Config) ApplyDefaults()
ApplyDefaults fills in any unset values with defaults.
type E2EChecksConfig ¶
type E2EChecksConfig struct {
// Base URL for the commitments API. If empty, defaults to defaultCommitmentsAPIURL.
BaseURL string `json:"baseURL"`
}
E2EChecksConfig holds the configuration for CR e2e checks.
type Flavor ¶
type Flavor struct {
ID string `json:"id"`
Disk int `json:"disk"` // in GB.
RAM int `json:"ram"` // in MB.
Name string `json:"name"`
RxTxFactor float64 `json:"rxtx_factor"`
VCPUs int `json:"vcpus"`
IsPublic bool `json:"os-flavor-access:is_public"`
Ephemeral int `json:"OS-FLV-EXT-DATA:ephemeral"`
Description string `json:"description"`
// JSON string of extra specifications used when scheduling the flavor.
ExtraSpecs map[string]string `json:"extra_specs" db:"extra_specs"`
}
OpenStack flavor model as returned by the Nova API under /flavors/detail. See: https://docs.openstack.org/api-ref/compute/#list-flavors
type HTTPAPI ¶
type HTTPAPI struct {
// contains filtered or unexported fields
}
HTTPAPI implements Limes LIQUID commitment validation endpoints.
func NewAPIWithConfig ¶
func NewAPIWithConfig(client client.Client, config Config, novaClient UsageNovaClient) *HTTPAPI
func (*HTTPAPI) HandleChangeCommitments ¶
func (api *HTTPAPI) HandleChangeCommitments(w http.ResponseWriter, r *http.Request)
implements POST /commitments/v1/change-commitments from Limes LIQUID API: See: https://github.com/sapcc/go-api-declarations/blob/main/liquid/commitment.go See: https://pkg.go.dev/github.com/sapcc/go-api-declarations/liquid
This endpoint handles commitment changes by creating/updating/deleting Reservation CRDs based on the commitment lifecycle. A request may contain multiple commitment changes which are processed in a single transaction. If any change fails, all changes are rolled back.
func (*HTTPAPI) HandleInfo ¶
func (api *HTTPAPI) HandleInfo(w http.ResponseWriter, r *http.Request)
handles GET /commitments/v1/info requests from Limes: See: https://github.com/sapcc/go-api-declarations/blob/main/liquid/commitment.go See: https://pkg.go.dev/github.com/sapcc/go-api-declarations/liquid
func (*HTTPAPI) HandleQuota ¶
func (api *HTTPAPI) HandleQuota(w http.ResponseWriter, r *http.Request)
HandleQuota implements PUT /commitments/v1/projects/:project_id/quota from Limes LIQUID API. See: https://pkg.go.dev/github.com/sapcc/go-api-declarations/liquid
This is a no-op endpoint that accepts quota requests but doesn't store them. Cortex does not enforce quotas for committed resources - quota enforcement happens through commitment validation at change-commitments time. The endpoint exists for API compatibility with the LIQUID specification.
func (*HTTPAPI) HandleReportCapacity ¶
func (api *HTTPAPI) HandleReportCapacity(w http.ResponseWriter, r *http.Request)
handles POST /commitments/v1/report-capacity requests from Limes: See: https://github.com/sapcc/go-api-declarations/blob/main/liquid/commitment.go See: https://pkg.go.dev/github.com/sapcc/go-api-declarations/liquid Reports available capacity across all flavor group resources. Note, unit is specified in the Info API response with multiple of the smallest memory resource unit within a flavor group.
func (*HTTPAPI) HandleReportUsage ¶
func (api *HTTPAPI) HandleReportUsage(w http.ResponseWriter, r *http.Request)
HandleReportUsage implements POST /commitments/v1/projects/:project_id/report-usage from Limes LIQUID API. See: https://github.com/sapcc/go-api-declarations/blob/main/liquid/report_usage.go See: https://pkg.go.dev/github.com/sapcc/go-api-declarations/liquid
This endpoint reports usage information for a specific project's committed resources, including per-AZ usage, physical usage, and detailed VM subresources.
func (*HTTPAPI) Init ¶
func (api *HTTPAPI) Init(mux *http.ServeMux, registry prometheus.Registerer, log logr.Logger)
type InfoAPIMonitor ¶
type InfoAPIMonitor struct {
// contains filtered or unexported fields
}
InfoAPIMonitor provides metrics for the CR info API.
func NewInfoAPIMonitor ¶
func NewInfoAPIMonitor() InfoAPIMonitor
NewInfoAPIMonitor creates a new monitor with Prometheus metrics. Metrics are pre-initialized with zero values for common HTTP status codes to ensure they appear in Prometheus before the first request.
func (*InfoAPIMonitor) Collect ¶
func (m *InfoAPIMonitor) Collect(ch chan<- prometheus.Metric)
Collect implements prometheus.Collector.
func (*InfoAPIMonitor) Describe ¶
func (m *InfoAPIMonitor) Describe(ch chan<- *prometheus.Desc)
Describe implements prometheus.Collector.
type Project ¶
type Project struct {
// DomainID is the domain ID the project belongs to.
DomainID string `json:"domain_id"`
// ID is the unique ID of the project.
ID string `json:"id"`
// Name is the name of the project.
Name string `json:"name"`
// ParentID is the parent_id of the project.
ParentID string `json:"parent_id"`
}
OpenStack project model as returned by the Keystone API under /projects. See: https://docs.openstack.org/api-ref/identity/v3/#projects
type ReportCapacityAPIMonitor ¶
type ReportCapacityAPIMonitor struct {
// contains filtered or unexported fields
}
ReportCapacityAPIMonitor provides metrics for the CR report-capacity API.
func NewReportCapacityAPIMonitor ¶
func NewReportCapacityAPIMonitor() ReportCapacityAPIMonitor
NewReportCapacityAPIMonitor creates a new monitor with Prometheus metrics. Metrics are pre-initialized with zero values for common HTTP status codes to ensure they appear in Prometheus before the first request.
func (*ReportCapacityAPIMonitor) Collect ¶
func (m *ReportCapacityAPIMonitor) Collect(ch chan<- prometheus.Metric)
Collect implements prometheus.Collector.
func (*ReportCapacityAPIMonitor) Describe ¶
func (m *ReportCapacityAPIMonitor) Describe(ch chan<- *prometheus.Desc)
Describe implements prometheus.Collector.
type ReportUsageAPIMonitor ¶
type ReportUsageAPIMonitor struct {
// contains filtered or unexported fields
}
ReportUsageAPIMonitor provides metrics for the CR report-usage API.
func NewReportUsageAPIMonitor ¶
func NewReportUsageAPIMonitor() ReportUsageAPIMonitor
NewReportUsageAPIMonitor creates a new monitor with Prometheus metrics. Metrics are pre-initialized with zero values for common HTTP status codes to ensure they appear in Prometheus before the first request.
func (*ReportUsageAPIMonitor) Collect ¶
func (m *ReportUsageAPIMonitor) Collect(ch chan<- prometheus.Metric)
Collect implements prometheus.Collector.
func (*ReportUsageAPIMonitor) Describe ¶
func (m *ReportUsageAPIMonitor) Describe(ch chan<- *prometheus.Desc)
Describe implements prometheus.Collector.
type ReservationManager ¶
ReservationManager handles CRUD operations for Reservation CRDs.
func NewReservationManager ¶
func NewReservationManager(k8sClient client.Client) *ReservationManager
func (*ReservationManager) ApplyCommitmentState ¶
func (m *ReservationManager) ApplyCommitmentState( ctx context.Context, log logr.Logger, desiredState *CommitmentState, flavorGroups map[string]compute.FlavorGroupFeature, creator string, ) (*ApplyResult, error)
ApplyCommitmentState synchronizes Reservation CRDs to match the desired commitment state. This function performs CRUD operations (create/update/delete) on reservation slots to align with the capacity specified in desiredState.
Entry points:
- from Syncer - periodic sync with Limes state
- from API ChangeCommitmentsHandler - batch processing of commitment changes
The function is idempotent and handles:
- Repairing inconsistent slots (wrong flavor group/project)
- Creating new reservation slots when capacity increases
- Deleting unused/excess slots when capacity decreases
- Syncing reservation metadata for all remaining slots
Returns ApplyResult containing touched/removed reservations and counts for metrics.
type Server ¶
type Server struct {
ID string `json:"id" db:"id,primarykey"`
Name string `json:"name" db:"name"`
Status string `json:"status" db:"status"`
TenantID string `json:"tenant_id" db:"tenant_id"`
UserID string `json:"user_id" db:"user_id"`
HostID string `json:"hostId" db:"host_id"`
Created string `json:"created" db:"created"`
Updated string `json:"updated" db:"updated"`
AccessIPv4 string `json:"accessIPv4" db:"access_ipv4"`
AccessIPv6 string `json:"accessIPv6" db:"access_ipv6"`
OSDCFdiskConfig string `json:"OS-DCF:diskConfig" db:"os_dcf_disk_config"`
Progress int `json:"progress" db:"progress"`
OSEXTAvailabilityZone string `json:"OS-EXT-AZ:availability_zone" db:"os_ext_az_availability_zone"`
ConfigDrive string `json:"config_drive" db:"config_drive"`
KeyName string `json:"key_name" db:"key_name"`
OSSRVUSGLaunchedAt string `json:"OS-SRV-USG:launched_at" db:"os_srv_usg_launched_at"`
OSSRVUSGTerminatedAt *string `json:"OS-SRV-USG:terminated_at" db:"os_srv_usg_terminated_at"`
OSEXTSRVATTRHost string `json:"OS-EXT-SRV-ATTR:host" db:"os_ext_srv_attr_host"`
OSEXTSRVATTRInstanceName string `json:"OS-EXT-SRV-ATTR:instance_name" db:"os_ext_srv_attr_instance_name"`
OSEXTSRVATTRHypervisorHostname string `json:"OS-EXT-SRV-ATTR:hypervisor_hostname" db:"os_ext_srv_attr_hypervisor_hostname"`
OSEXTSTSTaskState *string `json:"OS-EXT-STS:task_state" db:"os_ext_sts_task_state"`
OSEXTSTSVmState string `json:"OS-EXT-STS:vm_state" db:"os_ext_sts_vm_state"`
OSEXTSTSPowerState int `json:"OS-EXT-STS:power_state" db:"os_ext_sts_power_state"`
// From nested JSON
FlavorName string `json:"-" db:"flavor_name"`
}
OpenStack server model as returned by the Nova API under /servers/detail. See: https://docs.openstack.org/api-ref/compute/#list-servers-detailed
func (*Server) MarshalJSON ¶
Custom marshaler for OpenStackServer to handle nested JSON.
func (*Server) UnmarshalJSON ¶
Custom unmarshaler for OpenStackServer to handle nested JSON.
type Syncer ¶
type Syncer struct {
// Client to fetch commitments from Limes
CommitmentsClient
// Kubernetes client for CRD operations
client.Client
// contains filtered or unexported fields
}
type SyncerConfig ¶
type SyncerConfig struct {
// Secret ref to keystone credentials stored in a k8s secret.
KeystoneSecretRef corev1.SecretReference `json:"keystoneSecretRef"`
// Secret ref to SSO credentials stored in a k8s secret, if applicable.
SSOSecretRef *corev1.SecretReference `json:"ssoSecretRef"`
// SyncInterval defines how often the syncer reconciles Limes commitments to Reservation CRDs.
SyncInterval time.Duration `json:"committedResourceSyncInterval"`
}
func DefaultSyncerConfig ¶
func DefaultSyncerConfig() SyncerConfig
func (*SyncerConfig) ApplyDefaults ¶
func (c *SyncerConfig) ApplyDefaults()
ApplyDefaults fills in any unset values with defaults.
type SyncerMonitor ¶
type SyncerMonitor struct {
// contains filtered or unexported fields
}
SyncerMonitor provides metrics for the commitment syncer.
func NewSyncerMonitor ¶
func NewSyncerMonitor() *SyncerMonitor
NewSyncerMonitor creates a new monitor with Prometheus metrics.
func (*SyncerMonitor) Collect ¶
func (m *SyncerMonitor) Collect(ch chan<- prometheus.Metric)
Collect implements prometheus.Collector.
func (*SyncerMonitor) Describe ¶
func (m *SyncerMonitor) Describe(ch chan<- *prometheus.Desc)
Describe implements prometheus.Collector.
func (*SyncerMonitor) RecordCommitmentProcessed ¶
func (m *SyncerMonitor) RecordCommitmentProcessed()
RecordCommitmentProcessed records a commitment successfully processed.
func (*SyncerMonitor) RecordCommitmentSeen ¶
func (m *SyncerMonitor) RecordCommitmentSeen()
RecordCommitmentSeen records a commitment seen from Limes.
func (*SyncerMonitor) RecordCommitmentSkipped ¶
func (m *SyncerMonitor) RecordCommitmentSkipped(reason string)
RecordCommitmentSkipped records a commitment skipped with a reason.
func (*SyncerMonitor) RecordReservationsCreated ¶
func (m *SyncerMonitor) RecordReservationsCreated(count int)
RecordReservationsCreated records reservations created.
func (*SyncerMonitor) RecordReservationsDeleted ¶
func (m *SyncerMonitor) RecordReservationsDeleted(count int)
RecordReservationsDeleted records reservations deleted.
func (*SyncerMonitor) RecordReservationsRepaired ¶
func (m *SyncerMonitor) RecordReservationsRepaired(count int)
RecordReservationsRepaired records reservations repaired.
func (*SyncerMonitor) RecordSyncError ¶
func (m *SyncerMonitor) RecordSyncError()
RecordSyncError records a syncer error.
func (*SyncerMonitor) RecordSyncRun ¶
func (m *SyncerMonitor) RecordSyncRun()
RecordSyncRun records a syncer run.
func (*SyncerMonitor) RecordUnitMismatch ¶
func (m *SyncerMonitor) RecordUnitMismatch(_ string)
RecordUnitMismatch records a unit mismatch skip (convenience method).
type UsageCalculator ¶
type UsageCalculator struct {
// contains filtered or unexported fields
}
UsageCalculator computes usage reports for Limes LIQUID API.
func NewUsageCalculator ¶
func NewUsageCalculator(client client.Client, novaClient UsageNovaClient) *UsageCalculator
NewUsageCalculator creates a new UsageCalculator instance.
func (*UsageCalculator) CalculateUsage ¶
func (c *UsageCalculator) CalculateUsage( ctx context.Context, log logr.Logger, projectID string, allAZs []liquid.AvailabilityZone, ) (liquid.ServiceUsageReport, error)
CalculateUsage computes the usage report for a specific project.
type UsageNovaClient ¶
type UsageNovaClient interface {
ListProjectServers(ctx context.Context, projectID string) ([]nova.ServerDetail, error)
}
UsageNovaClient is a minimal interface for the Nova client needed by the usage API. This allows for easy mocking in tests without implementing the full NovaClient interface.
type VMUsageInfo ¶
type VMUsageInfo struct {
UUID string
Name string
FlavorName string
FlavorGroup string
Status string
MemoryMB uint64
VCPUs uint64
DiskGB uint64
AZ string
Hypervisor string
CreatedAt time.Time
UsageMultiple uint64 // Memory in multiples of smallest flavor in the group
Metadata map[string]string // Server metadata from Nova
Tags []string // Server tags from Nova
OSType string // OS type from OSTypeProber (for billing)
}
VMUsageInfo contains VM information needed for usage calculation. This is a local view of the VM enriched with flavor group information.
Source Files
¶
- api.go
- api_change_commitments.go
- api_change_commitments_metrics.go
- api_change_commitments_monitor.go
- api_info.go
- api_info_monitor.go
- api_quota.go
- api_report_capacity.go
- api_report_capacity_monitor.go
- api_report_usage.go
- api_report_usage_monitor.go
- capacity.go
- client.go
- config.go
- context.go
- controller.go
- e2e_checks.go
- flavor_group_eligibility.go
- messages.go
- reservation_manager.go
- state.go
- syncer.go
- syncer_monitor.go
- usage.go
- utils.go