Files
CLICD/backend/internal/api/images_custom_test.go
T

134 lines
3.8 KiB
Go

package api
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"path/filepath"
"runtime"
"strings"
"testing"
)
func TestCustomKVMImageCreateRejectsInvalidSource(t *testing.T) {
payload := map[string]string{
"name": "Invalid Source",
"distro": "ubuntu",
"release": "noble",
"arch": runtime.GOARCH,
"url": "file:///etc/passwd",
"provisioner": "linux-cloud-init",
}
body, err := json.Marshal(payload)
if err != nil {
t.Fatal(err)
}
request := httptest.NewRequest(http.MethodPost, "/api/images/custom", bytes.NewReader(body))
response := httptest.NewRecorder()
HandleCustomKVMImages(response, request)
if response.Code != http.StatusBadRequest {
t.Fatalf("status = %d, want %d; body=%s", response.Code, http.StatusBadRequest, response.Body.String())
}
}
func TestCustomKVMImageCreateRejectsArchitectureMismatch(t *testing.T) {
otherArch := "arm64"
if runtime.GOARCH == otherArch {
otherArch = "amd64"
}
payload := map[string]string{
"name": "Wrong Architecture",
"distro": "ubuntu",
"release": "noble",
"arch": otherArch,
"url": "https://example.test/image.qcow2",
"provisioner": "linux-cloud-init",
}
body, err := json.Marshal(payload)
if err != nil {
t.Fatal(err)
}
request := httptest.NewRequest(http.MethodPost, "/api/images/custom", bytes.NewReader(body))
response := httptest.NewRecorder()
HandleCustomKVMImages(response, request)
if response.Code != http.StatusBadRequest {
t.Fatalf("status = %d, want %d; body=%s", response.Code, http.StatusBadRequest, response.Body.String())
}
}
func TestCustomLXCImageCreateRejectsInvalidSource(t *testing.T) {
payload := map[string]string{
"type": "lxc",
"name": "Invalid LXC Source",
"distro": "alpine",
"release": "3.21",
"arch": runtime.GOARCH,
"url": "file:///tmp/rootfs.tar.xz",
}
body, err := json.Marshal(payload)
if err != nil {
t.Fatal(err)
}
request := httptest.NewRequest(http.MethodPost, "/api/images/custom", bytes.NewReader(body))
response := httptest.NewRecorder()
HandleCustomKVMImages(response, request)
if response.Code != http.StatusBadRequest {
t.Fatalf("status = %d, want %d; body=%s", response.Code, http.StatusBadRequest, response.Body.String())
}
}
func TestCustomImageCreateRejectsPrivateNetworkSource(t *testing.T) {
for _, imageType := range []string{"lxc", "kvm"} {
t.Run(imageType, func(t *testing.T) {
payload := map[string]string{
"type": imageType,
"name": "Private Network Source",
"distro": "ubuntu",
"release": "noble",
"arch": runtime.GOARCH,
"url": "http://169.254.169.254/latest/meta-data",
"provisioner": "linux-cloud-init",
}
body, err := json.Marshal(payload)
if err != nil {
t.Fatal(err)
}
request := httptest.NewRequest(http.MethodPost, "/api/images/custom", bytes.NewReader(body))
response := httptest.NewRecorder()
HandleCustomKVMImages(response, request)
if response.Code != http.StatusBadRequest {
t.Fatalf("status = %d, want %d; body=%s", response.Code, http.StatusBadRequest, response.Body.String())
}
})
}
}
func TestOfficialLXCImageCachePathUsesAllowlist(t *testing.T) {
cachePath, ok := officialLXCImageCachePath("debian-trixie")
if !ok {
t.Fatal("known template cache path was rejected")
}
normalized := filepath.ToSlash(cachePath)
if !strings.Contains(normalized, "/debian/trixie/") {
t.Fatalf("cache path = %q, want Debian trixie path", cachePath)
}
for _, templateID := range []string{
"../../../etc",
"custom-lxc-attacker",
"debian-trixie/../../etc",
} {
if cachePath, ok := officialLXCImageCachePath(templateID); ok || cachePath != "" {
t.Fatalf("officialLXCImageCachePath(%q) = %q, %v; want rejection", templateID, cachePath, ok)
}
}
}