Skip to content

Commit 7e9bf50

Browse files
Scaffold empty placement api handlers
1 parent 88b2cb4 commit 7e9bf50

15 files changed

Lines changed: 744 additions & 0 deletions

cmd/shim/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"path/filepath"
1313

1414
"github.com/cobaltcore-dev/cortex/api/v1alpha1"
15+
placementhandlers "github.com/cobaltcore-dev/cortex/internal/shim/placement/handlers"
1516
"github.com/cobaltcore-dev/cortex/pkg/conf"
1617
"github.com/cobaltcore-dev/cortex/pkg/monitoring"
1718
hv1 "github.com/cobaltcore-dev/openstack-hypervisor-operator/api/v1"
@@ -57,6 +58,7 @@ func main() {
5758
var probeAddr string
5859
var secureMetrics bool
5960
var enableHTTP2 bool
61+
var enablePlacementShim bool
6062
var tlsOpts []func(*tls.Config)
6163
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
6264
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
@@ -75,6 +77,8 @@ func main() {
7577
flag.StringVar(&metricsCertKey, "metrics-cert-key", "tls.key", "The name of the metrics server key file.")
7678
flag.BoolVar(&enableHTTP2, "enable-http2", false,
7779
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
80+
flag.BoolVar(&enablePlacementShim, "placement-shim", false,
81+
"If set, the placement API shim handlers are registered on the API server.")
7882
opts := zap.Options{
7983
Development: true,
8084
}
@@ -202,6 +206,9 @@ func main() {
202206

203207
// API endpoint.
204208
mux := http.NewServeMux()
209+
if enablePlacementShim {
210+
placementhandlers.RegisterRoutes(mux)
211+
}
205212

206213
// +kubebuilder:scaffold:builder
207214

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright SAP SE
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package handlers
5+
6+
import (
7+
"net/http"
8+
9+
logf "sigs.k8s.io/controller-runtime/pkg/log"
10+
)
11+
12+
// HandleListAllocationCandidates handles GET /allocation_candidates requests.
13+
//
14+
// Returns a collection of allocation requests and resource provider summaries
15+
// that can satisfy a given set of resource and trait requirements. This is the
16+
// primary endpoint used by Nova's scheduler to find suitable hosts for
17+
// instance placement.
18+
//
19+
// The resources query parameter specifies required capacity as a comma-
20+
// separated list (e.g. VCPU:4,MEMORY_MB:2048,DISK_GB:64). The required
21+
// parameter filters by traits, supporting forbidden traits via ! prefix
22+
// (since 1.22) and the in: syntax for any-of semantics (since 1.39).
23+
// The member_of parameter filters by aggregate membership with support for
24+
// forbidden aggregates via ! prefix (since 1.32).
25+
//
26+
// Since microversion 1.25, granular request groups are supported via numbered
27+
// suffixes (resourcesN, requiredN, member_ofN) to express requirements that
28+
// may be satisfied by different providers. The group_policy parameter (1.26+)
29+
// controls whether groups must each be satisfied by a single provider or may
30+
// span multiple. The in_tree parameter (1.31+) constrains results to a
31+
// specific provider tree.
32+
//
33+
// Each returned allocation request is directly usable as the body for
34+
// PUT /allocations/{consumer_uuid}. The provider_summaries section includes
35+
// inventory capacity and usage for informed decision-making. Available since
36+
// microversion 1.10.
37+
func HandleListAllocationCandidates(w http.ResponseWriter, r *http.Request) {
38+
log := logf.FromContext(r.Context())
39+
log.Info("placement request", "method", r.Method, "path", r.URL.Path)
40+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright SAP SE
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package handlers
5+
6+
import (
7+
"net/http"
8+
9+
logf "sigs.k8s.io/controller-runtime/pkg/log"
10+
)
11+
12+
// HandleManageAllocations handles POST /allocations requests.
13+
//
14+
// Atomically creates, updates, or deletes allocations for multiple consumers
15+
// in a single request. This is the primary mechanism for operations that must
16+
// modify allocations across several consumers atomically, such as live
17+
// migrations and move operations where resources are transferred from one
18+
// consumer to another. Available since microversion 1.13.
19+
//
20+
// The request body is keyed by consumer UUID, each containing an allocations
21+
// dictionary (keyed by resource provider UUID), along with project_id and
22+
// user_id. Since microversion 1.28, consumer_generation enables consumer-
23+
// level concurrency control. Since microversion 1.38, a consumer_type field
24+
// (e.g. INSTANCE, MIGRATION) is supported. Returns 204 No Content on
25+
// success, or 409 Conflict if inventory is insufficient or a concurrent
26+
// update is detected (error code: placement.concurrent_update).
27+
func HandleManageAllocations(w http.ResponseWriter, r *http.Request) {
28+
log := logf.FromContext(r.Context())
29+
log.Info("placement request", "method", r.Method, "path", r.URL.Path)
30+
}
31+
32+
// HandleListAllocations handles GET /allocations/{consumer_uuid} requests.
33+
//
34+
// Returns all allocation records for the consumer identified by
35+
// {consumer_uuid}, across all resource providers. The response contains an
36+
// allocations dictionary keyed by resource provider UUID. If the consumer has
37+
// no allocations, an empty dictionary is returned.
38+
//
39+
// The response has grown across microversions: project_id and user_id were
40+
// added at 1.12, consumer_generation at 1.28, and consumer_type at 1.38.
41+
// The consumer_generation and consumer_type fields are absent when the
42+
// consumer has no allocations.
43+
func HandleListAllocations(w http.ResponseWriter, r *http.Request) {
44+
consumerUUID := r.PathValue("consumer_uuid")
45+
log := logf.FromContext(r.Context())
46+
log.Info("placement request", "method", r.Method, "path", r.URL.Path,
47+
"consumer_uuid", consumerUUID)
48+
}
49+
50+
// HandleUpdateAllocations handles PUT /allocations/{consumer_uuid} requests.
51+
//
52+
// Creates or replaces all allocation records for a single consumer. If
53+
// allocations already exist for this consumer, they are entirely replaced
54+
// by the new set. The request format changed at microversion 1.12 from an
55+
// array-based layout to an object keyed by resource provider UUID.
56+
// Microversion 1.28 added consumer_generation for concurrency control,
57+
// and 1.38 introduced consumer_type.
58+
//
59+
// Returns 204 No Content on success. Returns 409 Conflict if there is
60+
// insufficient inventory or if a concurrent update was detected.
61+
func HandleUpdateAllocations(w http.ResponseWriter, r *http.Request) {
62+
consumerUUID := r.PathValue("consumer_uuid")
63+
log := logf.FromContext(r.Context())
64+
log.Info("placement request", "method", r.Method, "path", r.URL.Path,
65+
"consumer_uuid", consumerUUID)
66+
}
67+
68+
// HandleDeleteAllocations handles DELETE /allocations/{consumer_uuid} requests.
69+
//
70+
// Removes all allocation records for the consumer across all resource
71+
// providers. Returns 204 No Content on success, or 404 Not Found if the
72+
// consumer has no existing allocations.
73+
func HandleDeleteAllocations(w http.ResponseWriter, r *http.Request) {
74+
consumerUUID := r.PathValue("consumer_uuid")
75+
log := logf.FromContext(r.Context())
76+
log.Info("placement request", "method", r.Method, "path", r.URL.Path,
77+
"consumer_uuid", consumerUUID)
78+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright SAP SE
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package handlers
5+
6+
import (
7+
"net/http"
8+
9+
logf "sigs.k8s.io/controller-runtime/pkg/log"
10+
)
11+
12+
// HandlePostReshaper handles POST /reshaper requests.
13+
//
14+
// Atomically migrates resource provider inventories and associated allocations
15+
// in a single transaction. This endpoint is used when a provider tree needs to
16+
// be restructured — for example, moving inventory from a root provider into
17+
// newly created child providers — without leaving allocations in an
18+
// inconsistent state during the transition.
19+
//
20+
// The request body contains the complete set of inventories (keyed by
21+
// resource provider UUID) and allocations (keyed by consumer UUID) that
22+
// should exist after the operation. The Placement service validates all
23+
// inputs atomically and applies them in a single database transaction.
24+
// Returns 204 No Content on success. Returns 409 Conflict if any referenced
25+
// resource provider does not exist or if inventory/allocation constraints
26+
// would be violated. Available since microversion 1.30.
27+
func HandlePostReshaper(w http.ResponseWriter, r *http.Request) {
28+
log := logf.FromContext(r.Context())
29+
log.Info("placement request", "method", r.Method, "path", r.URL.Path)
30+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright SAP SE
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package handlers
5+
6+
import (
7+
"net/http"
8+
9+
logf "sigs.k8s.io/controller-runtime/pkg/log"
10+
)
11+
12+
// HandleListResourceClasses handles GET /resource_classes requests.
13+
//
14+
// Returns the complete list of all resource classes, including both standard
15+
// classes (e.g. VCPU, MEMORY_MB, DISK_GB, PCI_DEVICE, SRIOV_NET_VF) and
16+
// deployer-defined custom classes prefixed with CUSTOM_. Resource classes
17+
// categorize the types of resources that resource providers can offer as
18+
// inventory. Available since microversion 1.2.
19+
func HandleListResourceClasses(w http.ResponseWriter, r *http.Request) {
20+
log := logf.FromContext(r.Context())
21+
log.Info("placement request", "method", r.Method, "path", r.URL.Path)
22+
}
23+
24+
// HandleCreateResourceClass handles POST /resource_classes requests.
25+
//
26+
// Creates a new custom resource class. The name must be prefixed with CUSTOM_
27+
// to distinguish it from standard resource classes. Returns 201 Created with
28+
// a Location header on success. Returns 400 Bad Request if the CUSTOM_ prefix
29+
// is missing, and 409 Conflict if a class with the same name already exists.
30+
// Available since microversion 1.2.
31+
func HandleCreateResourceClass(w http.ResponseWriter, r *http.Request) {
32+
log := logf.FromContext(r.Context())
33+
log.Info("placement request", "method", r.Method, "path", r.URL.Path)
34+
}
35+
36+
// HandleShowResourceClass handles GET /resource_classes/{name} requests.
37+
//
38+
// Returns a representation of a single resource class identified by name.
39+
// This can be used to verify the existence of a resource class. Returns 404
40+
// if the class does not exist. Available since microversion 1.2.
41+
func HandleShowResourceClass(w http.ResponseWriter, r *http.Request) {
42+
name := r.PathValue("name")
43+
log := logf.FromContext(r.Context())
44+
log.Info("placement request", "method", r.Method, "path", r.URL.Path, "name", name)
45+
}
46+
47+
// HandleUpdateResourceClass handles PUT /resource_classes/{name} requests.
48+
//
49+
// Behavior differs by microversion. Since microversion 1.7, this endpoint
50+
// creates or validates the existence of a single resource class: it returns
51+
// 201 Created for a new class or 204 No Content if the class already exists.
52+
// The name must carry the CUSTOM_ prefix. In earlier versions (1.2-1.6), the
53+
// endpoint allowed renaming a class via a request body, but this usage is
54+
// discouraged. Returns 400 Bad Request if the CUSTOM_ prefix is missing.
55+
func HandleUpdateResourceClass(w http.ResponseWriter, r *http.Request) {
56+
name := r.PathValue("name")
57+
log := logf.FromContext(r.Context())
58+
log.Info("placement request", "method", r.Method, "path", r.URL.Path, "name", name)
59+
}
60+
61+
// HandleDeleteResourceClass handles DELETE /resource_classes/{name} requests.
62+
//
63+
// Deletes a custom resource class. Only custom classes (prefixed with CUSTOM_)
64+
// may be deleted; attempting to delete a standard class returns 400 Bad
65+
// Request. Returns 409 Conflict if any resource provider has inventory of this
66+
// class, and 404 if the class does not exist. Returns 204 No Content on
67+
// success. Available since microversion 1.2.
68+
func HandleDeleteResourceClass(w http.ResponseWriter, r *http.Request) {
69+
name := r.PathValue("name")
70+
log := logf.FromContext(r.Context())
71+
log.Info("placement request", "method", r.Method, "path", r.URL.Path, "name", name)
72+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright SAP SE
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package handlers
5+
6+
import (
7+
"net/http"
8+
9+
logf "sigs.k8s.io/controller-runtime/pkg/log"
10+
)
11+
12+
// HandleListResourceProviderAggregates handles
13+
// GET /resource_providers/{uuid}/aggregates requests.
14+
//
15+
// Returns the list of aggregate UUIDs associated with the resource provider.
16+
// Aggregates model relationships among providers such as shared storage,
17+
// affinity/anti-affinity groups, and availability zones. Returns an empty
18+
// list if the provider has no aggregate associations. Available since
19+
// microversion 1.1.
20+
//
21+
// The response format changed at microversion 1.19: earlier versions return
22+
// only a flat array of UUIDs, while 1.19+ returns an object that also
23+
// includes the resource_provider_generation for concurrency tracking. Returns
24+
// 404 if the provider does not exist.
25+
func HandleListResourceProviderAggregates(w http.ResponseWriter, r *http.Request) {
26+
uuid := r.PathValue("uuid")
27+
log := logf.FromContext(r.Context())
28+
log.Info("placement request", "method", r.Method, "path", r.URL.Path, "uuid", uuid)
29+
}
30+
31+
// HandleUpdateResourceProviderAggregates handles
32+
// PUT /resource_providers/{uuid}/aggregates requests.
33+
//
34+
// Replaces the complete set of aggregate associations for a resource provider.
35+
// Any aggregate UUIDs that do not yet exist are created automatically. The
36+
// request format changed at microversion 1.19: earlier versions accept a
37+
// plain array of UUIDs, while 1.19+ expects an object containing an
38+
// aggregates array and a resource_provider_generation for optimistic
39+
// concurrency control. Returns 409 Conflict if the generation does not match
40+
// (1.19+). Returns 200 with the updated aggregate list on success.
41+
func HandleUpdateResourceProviderAggregates(w http.ResponseWriter, r *http.Request) {
42+
uuid := r.PathValue("uuid")
43+
log := logf.FromContext(r.Context())
44+
log.Info("placement request", "method", r.Method, "path", r.URL.Path, "uuid", uuid)
45+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright SAP SE
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package handlers
5+
6+
import (
7+
"net/http"
8+
9+
logf "sigs.k8s.io/controller-runtime/pkg/log"
10+
)
11+
12+
// HandleListResourceProviderAllocations handles
13+
// GET /resource_providers/{uuid}/allocations requests.
14+
//
15+
// Returns all allocations made against the resource provider identified by
16+
// {uuid}, keyed by consumer UUID. This provides a provider-centric view of
17+
// consumption, complementing the consumer-centric GET /allocations/{consumer}
18+
// endpoint. The response includes the resource_provider_generation. Returns
19+
// 404 if the provider does not exist.
20+
func HandleListResourceProviderAllocations(w http.ResponseWriter, r *http.Request) {
21+
uuid := r.PathValue("uuid")
22+
log := logf.FromContext(r.Context())
23+
log.Info("placement request", "method", r.Method, "path", r.URL.Path, "uuid", uuid)
24+
}

0 commit comments

Comments
 (0)