Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup internal API endpoints #1747

Merged
merged 2 commits into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 0 additions & 30 deletions cmd/incusd/api_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,36 +79,6 @@ var clusterNodeStateCmd = APIEndpoint{
Post: APIEndpointAction{Handler: clusterNodeStatePost, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalClusterAcceptCmd = APIEndpoint{
Path: "cluster/accept",

Post: APIEndpointAction{Handler: internalClusterPostAccept, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalClusterRebalanceCmd = APIEndpoint{
Path: "cluster/rebalance",

Post: APIEndpointAction{Handler: internalClusterPostRebalance, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalClusterAssignCmd = APIEndpoint{
Path: "cluster/assign",

Post: APIEndpointAction{Handler: internalClusterPostAssign, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalClusterHandoverCmd = APIEndpoint{
Path: "cluster/handover",

Post: APIEndpointAction{Handler: internalClusterPostHandover, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalClusterRaftNodeCmd = APIEndpoint{
Path: "cluster/raft-node/{address}",

Delete: APIEndpointAction{Handler: internalClusterRaftNodeDelete, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

// swagger:operation GET /1.0/cluster cluster cluster_get
//
// Get the cluster configuration
Expand Down
98 changes: 67 additions & 31 deletions cmd/incusd/api_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,71 @@ var apiInternal = []APIEndpoint{
internalWarningCreateCmd,
}

// Daemon management internal commands.
var internalReadyCmd = APIEndpoint{
Path: "ready",

Get: APIEndpointAction{Handler: internalWaitReady, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalShutdownCmd = APIEndpoint{
Path: "shutdown",

Put: APIEndpointAction{Handler: internalShutdown, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalReadyCmd = APIEndpoint{
Path: "ready",
// Internal managemnt traffic.
var internalImageOptimizeCmd = APIEndpoint{
Path: "image-optimize",

Get: APIEndpointAction{Handler: internalWaitReady, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
Post: APIEndpointAction{Handler: internalOptimizeImage, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalRebalanceLoadCmd = APIEndpoint{
Path: "rebalance",

Get: APIEndpointAction{Handler: internalRebalanceLoad, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalSQLCmd = APIEndpoint{
Path: "sql",

Get: APIEndpointAction{Handler: internalSQLGet, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
Post: APIEndpointAction{Handler: internalSQLPost, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

// Internal cluster traffic.
var internalClusterAcceptCmd = APIEndpoint{
Path: "cluster/accept",

Post: APIEndpointAction{Handler: internalClusterPostAccept, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalClusterAssignCmd = APIEndpoint{
Path: "cluster/assign",

Post: APIEndpointAction{Handler: internalClusterPostAssign, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalClusterHandoverCmd = APIEndpoint{
Path: "cluster/handover",

Post: APIEndpointAction{Handler: internalClusterPostHandover, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalClusterRaftNodeCmd = APIEndpoint{
Path: "cluster/raft-node/{address}",

Delete: APIEndpointAction{Handler: internalClusterRaftNodeDelete, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalClusterRebalanceCmd = APIEndpoint{
Path: "cluster/rebalance",

Post: APIEndpointAction{Handler: internalClusterPostRebalance, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

// Container hooks.
var internalContainerOnStartCmd = APIEndpoint{
Path: "containers/{instanceRef}/onstart",

Expand All @@ -99,61 +152,44 @@ var internalContainerOnStopCmd = APIEndpoint{
Get: APIEndpointAction{Handler: internalContainerOnStop, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

// Virtual machine hooks.
var internalVirtualMachineOnResizeCmd = APIEndpoint{
Path: "virtual-machines/{instanceRef}/onresize",

Get: APIEndpointAction{Handler: internalVirtualMachineOnResize, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalSQLCmd = APIEndpoint{
Path: "sql",
// Debugging.
var internalBGPStateCmd = APIEndpoint{
Path: "debug/bgp",

Get: APIEndpointAction{Handler: internalSQLGet, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
Post: APIEndpointAction{Handler: internalSQLPost, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
Get: APIEndpointAction{Handler: internalBGPState, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalGarbageCollectorCmd = APIEndpoint{
Path: "gc",
Path: "debug/gc",

Get: APIEndpointAction{Handler: internalGC, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalRAFTSnapshotCmd = APIEndpoint{
Path: "raft-snapshot",

Get: APIEndpointAction{Handler: internalRAFTSnapshot, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalImageRefreshCmd = APIEndpoint{
Path: "testing/image-refresh",
Path: "debug/image-refresh",

Get: APIEndpointAction{Handler: internalRefreshImage, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalImageOptimizeCmd = APIEndpoint{
Path: "image-optimize",
var internalRAFTSnapshotCmd = APIEndpoint{
Path: "debug/raft-snapshot",

Post: APIEndpointAction{Handler: internalOptimizeImage, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
Get: APIEndpointAction{Handler: internalRAFTSnapshot, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalWarningCreateCmd = APIEndpoint{
Path: "testing/warnings",
Path: "debug/warnings",

Post: APIEndpointAction{Handler: internalCreateWarning, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalBGPStateCmd = APIEndpoint{
Path: "testing/bgp",

Get: APIEndpointAction{Handler: internalBGPState, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

var internalRebalanceLoadCmd = APIEndpoint{
Path: "rebalance",

Get: APIEndpointAction{Handler: internalRebalanceLoad, AccessHandler: allowPermission(auth.ObjectTypeServer, auth.EntitlementCanEdit)},
}

type internalImageOptimizePost struct {
Image api.Image `json:"image" yaml:"image"`
Pool string `json:"pool" yaml:"pool"`
Expand Down
6 changes: 3 additions & 3 deletions test/suites/clustering.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2782,7 +2782,7 @@ test_clustering_image_refresh() {

# Trigger image refresh on all nodes
for incus_dir in "${INCUS_ONE_DIR}" "${INCUS_TWO_DIR}" "${INCUS_THREE_DIR}"; do
INCUS_DIR="${incus_dir}" incus query /internal/testing/image-refresh &
INCUS_DIR="${incus_dir}" incus query /internal/debug/image-refresh &
pids="$! ${pids}"
done

Expand Down Expand Up @@ -2820,7 +2820,7 @@ test_clustering_image_refresh() {
# Trigger image refresh on all nodes. This shouldn't do anything as the image
# is already up-to-date.
for incus_dir in "${INCUS_ONE_DIR}" "${INCUS_TWO_DIR}" "${INCUS_THREE_DIR}"; do
INCUS_DIR="${incus_dir}" incus query /internal/testing/image-refresh &
INCUS_DIR="${incus_dir}" incus query /internal/debug/image-refresh &
pids="$! ${pids}"
done

Expand All @@ -2846,7 +2846,7 @@ test_clustering_image_refresh() {

# Trigger image refresh on all nodes
for incus_dir in "${INCUS_ONE_DIR}" "${INCUS_TWO_DIR}" "${INCUS_THREE_DIR}"; do
INCUS_DIR="${incus_dir}" incus query /internal/testing/image-refresh &
INCUS_DIR="${incus_dir}" incus query /internal/debug/image-refresh &
pids="$! ${pids}"
done

Expand Down
2 changes: 1 addition & 1 deletion test/suites/fdleak.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ test_fdleak() {
done

incus list
incus query /internal/gc
incus query /internal/debug/gc

exit 0
)
Expand Down
8 changes: 4 additions & 4 deletions test/suites/network_forward.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ test_network_forward() {
incus network forward show "${netName}" 198.51.100.1 | grep -q -F "description: Test network forward"

# Check forward is exported via BGP prefixes.
incus query /internal/testing/bgp | grep "198.51.100.1/32"
incus query /internal/debug/bgp | grep "198.51.100.1/32"

incus network forward delete "${netName}" 198.51.100.1

# Check deleting network forward removes forward BGP prefix.
! incus query /internal/testing/bgp | grep "198.51.100.1/32" || false
! incus query /internal/debug/bgp | grep "198.51.100.1/32" || false

# Check creating forward with default target creates valid firewall rules.
incus network forward create "${netName}" 198.51.100.1 target_address=192.0.2.2
Expand Down Expand Up @@ -140,13 +140,13 @@ test_network_forward() {
fi

# Check forward is exported via BGP prefixes before network delete.
incus query /internal/testing/bgp | grep "198.51.100.1/32"
incus query /internal/debug/bgp | grep "198.51.100.1/32"

# Check deleting the network clears the forward firewall rules.
incus network delete "${netName}"

# Check deleting network removes forward BGP prefix.
! incus query /internal/testing/bgp | grep "198.51.100.1/32" || false
! incus query /internal/debug/bgp | grep "198.51.100.1/32" || false

if [ "$firewallDriver" = "xtables" ]; then
! iptables -w -t nat -S | grep -c "generated for Incus network-forward ${netName}" || false
Expand Down
14 changes: 7 additions & 7 deletions test/suites/warnings.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ test_warnings() {
incus query --wait /1.0/warnings\?recursion=1 | jq -r '.[].uuid' | xargs -n1 incus warning delete

# Create a global warning (no node and no project)
incus query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning\"}' /internal/testing/warnings
incus query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning\"}' /internal/debug/warnings

# More valid queries
incus query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning\", \"project\": \"default\"}' /internal/testing/warnings
incus query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning\", \"project\": \"default\"}' /internal/debug/warnings

# Update the last warning. This will not create a new warning.
incus query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning 2\", \"project\": \"default\"}' /internal/testing/warnings
incus query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning 2\", \"project\": \"default\"}' /internal/debug/warnings

# There should be two warnings now.
count=$(incus query --wait /1.0/warnings | jq 'length')
Expand All @@ -19,21 +19,21 @@ test_warnings() {
[ "${count}" -eq 2 ] || false

# Invalid query (unknown project)
! incus query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning\", \"project\": \"foo\"}' /internal/testing/warnings || false
! incus query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning\", \"project\": \"foo\"}' /internal/debug/warnings || false

# Invalid query (unknown type code)
! incus query --wait -X POST -d '{\"type_code\": 999, \"message\": \"global warning\"}' /internal/testing/warnings || false
! incus query --wait -X POST -d '{\"type_code\": 999, \"message\": \"global warning\"}' /internal/debug/warnings || false

# Both entity type code as entity ID need to be valid otherwise no warning will be created. Note that empty/null values are valid as well.
! incus query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning\", \"entity_type_code\": 0, \"entity_id\": 0}' /internal/testing/warnings || false
! incus query --wait -X POST -d '{\"type_code\": 0, \"message\": \"global warning\", \"entity_type_code\": 0, \"entity_id\": 0}' /internal/debug/warnings || false

ensure_import_testimage

# Get image ID from database instead of assuming it
image_id=$(echo 'select image_id from images_aliases where name="testimage"' | incus admin sql global - | grep -Eo '[[:digit:]]+')

# Create a warning with entity type "image" and entity ID ${image_id} (the imported testimage)
incus query --wait -X POST -d "{\\\"type_code\\\": 0, \\\"message\\\": \\\"global warning\\\", \\\"entity_type_code\\\": 1, \\\"entity_id\\\": ${image_id}}" /internal/testing/warnings
incus query --wait -X POST -d "{\\\"type_code\\\": 0, \\\"message\\\": \\\"global warning\\\", \\\"entity_type_code\\\": 1, \\\"entity_id\\\": ${image_id}}" /internal/debug/warnings

# There should be three warnings now.
count=$(incus warning list --format json | jq 'length')
Expand Down