Update .gitignore, remove package-lock.json, and enhance Cloudflare and Proxmox adapters
- Added lock file exclusions for pnpm in .gitignore. - Removed obsolete package-lock.json from the api and portal directories. - Enhanced Cloudflare adapter with additional interfaces for zones and tunnels. - Improved Proxmox adapter error handling and logging for API requests. - Updated Proxmox VM parameters with validation rules in the API schema. - Enhanced documentation for Proxmox VM specifications and examples.
This commit is contained in:
239
crossplane-provider-proxmox/pkg/utils/validation_test.go
Normal file
239
crossplane-provider-proxmox/pkg/utils/validation_test.go
Normal file
@@ -0,0 +1,239 @@
|
||||
package utils
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestValidateVMID(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
vmid int
|
||||
wantErr bool
|
||||
}{
|
||||
{"valid minimum", 100, false},
|
||||
{"valid maximum", 999999999, false},
|
||||
{"valid middle", 1000, false},
|
||||
{"too small", 99, true},
|
||||
{"zero", 0, true},
|
||||
{"negative", -1, true},
|
||||
{"too large", 1000000000, true},
|
||||
{"very large", 2000000000, true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateVMID(tt.vmid)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ValidateVMID(%d) error = %v, wantErr %v", tt.vmid, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateVMName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
vmName string
|
||||
wantErr bool
|
||||
}{
|
||||
// Valid names
|
||||
{"simple name", "vm-001", false},
|
||||
{"with underscore", "vm_001", false},
|
||||
{"with dot", "vm.001", false},
|
||||
{"with spaces", "my vm", false},
|
||||
{"alphanumeric", "vm001", false},
|
||||
{"mixed case", "MyVM", false},
|
||||
{"max length", string(make([]byte, 100)), false}, // 100 chars
|
||||
|
||||
// Invalid names
|
||||
{"empty", "", true},
|
||||
{"too long", string(make([]byte, 101)), true}, // 101 chars
|
||||
{"starts with space", " vm", true},
|
||||
{"ends with space", "vm ", true},
|
||||
{"invalid char @", "vm@001", true},
|
||||
{"invalid char #", "vm#001", true},
|
||||
{"invalid char $", "vm$001", true},
|
||||
{"invalid char %", "vm%001", true},
|
||||
{"only spaces", " ", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateVMName(tt.vmName)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ValidateVMName(%q) error = %v, wantErr %v", tt.vmName, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateMemory(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
memory string
|
||||
wantErr bool
|
||||
}{
|
||||
// Valid memory
|
||||
{"minimum", "128Mi", false},
|
||||
{"128MB", "128M", false},
|
||||
{"1Gi", "1Gi", false},
|
||||
{"4Gi", "4Gi", false},
|
||||
{"8Gi", "8Gi", false},
|
||||
{"16Gi", "16Gi", false},
|
||||
{"maximum", "2097152Mi", false}, // 2TB in MiB
|
||||
{"2TB in GiB", "2048Gi", false},
|
||||
|
||||
// Invalid memory
|
||||
{"empty", "", true},
|
||||
{"too small", "127Mi", true},
|
||||
{"too small MB", "127M", true},
|
||||
{"zero", "0", true},
|
||||
{"too large", "2097153Mi", true}, // Over 2TB
|
||||
{"too large GiB", "2049Gi", true},
|
||||
{"invalid format", "invalid", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateMemory(tt.memory)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ValidateMemory(%q) error = %v, wantErr %v", tt.memory, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateDisk(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
disk string
|
||||
wantErr bool
|
||||
}{
|
||||
// Valid disk
|
||||
{"minimum", "1Gi", false},
|
||||
{"1GB", "1G", false},
|
||||
{"10Gi", "10Gi", false},
|
||||
{"50Gi", "50Gi", false},
|
||||
{"100Gi", "100Gi", false},
|
||||
{"1Ti", "1Ti", false},
|
||||
{"maximum", "102400Gi", false}, // 100TB in GiB
|
||||
{"100TB in TiB", "100Ti", false},
|
||||
|
||||
// Invalid disk
|
||||
{"empty", "", true},
|
||||
{"too small", "0.5Gi", true}, // Less than 1GB
|
||||
{"zero", "0", true},
|
||||
{"too large", "102401Gi", true}, // Over 100TB
|
||||
{"too large TiB", "101Ti", true},
|
||||
{"invalid format", "invalid", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateDisk(tt.disk)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ValidateDisk(%q) error = %v, wantErr %v", tt.disk, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateCPU(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cpu int
|
||||
wantErr bool
|
||||
}{
|
||||
{"minimum", 1, false},
|
||||
{"valid", 2, false},
|
||||
{"valid", 4, false},
|
||||
{"valid", 8, false},
|
||||
{"maximum", 1024, false},
|
||||
{"zero", 0, true},
|
||||
{"negative", -1, true},
|
||||
{"too large", 1025, true},
|
||||
{"very large", 2048, true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateCPU(tt.cpu)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ValidateCPU(%d) error = %v, wantErr %v", tt.cpu, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateNetworkBridge(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
network string
|
||||
wantErr bool
|
||||
}{
|
||||
// Valid networks
|
||||
{"vmbr0", "vmbr0", false},
|
||||
{"vmbr1", "vmbr1", false},
|
||||
{"custom-bridge", "custom-bridge", false},
|
||||
{"custom_bridge", "custom_bridge", false},
|
||||
{"bridge01", "bridge01", false},
|
||||
{"BRIDGE", "BRIDGE", false},
|
||||
|
||||
// Invalid networks
|
||||
{"empty", "", true},
|
||||
{"with space", "vmbr 0", true},
|
||||
{"with @", "vmbr@0", true},
|
||||
{"with #", "vmbr#0", true},
|
||||
{"with $", "vmbr$0", true},
|
||||
{"with dot", "vmbr.0", true}, // Dots are typically not used in bridge names
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateNetworkBridge(tt.network)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ValidateNetworkBridge(%q) error = %v, wantErr %v", tt.network, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateImageSpec(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
image string
|
||||
wantErr bool
|
||||
}{
|
||||
// Valid template IDs
|
||||
{"valid template ID min", "100", false},
|
||||
{"valid template ID", "1000", false},
|
||||
{"valid template ID max", "999999999", false},
|
||||
|
||||
// Valid volid format
|
||||
{"valid volid", "local:iso/ubuntu-22.04.iso", false},
|
||||
{"valid volid with path", "storage:path/to/image.qcow2", false},
|
||||
|
||||
// Valid image names
|
||||
{"simple name", "ubuntu-22.04-cloud", false},
|
||||
{"with dots", "ubuntu.22.04.cloud", false},
|
||||
{"with hyphens", "ubuntu-22-04-cloud", false},
|
||||
{"with underscores", "ubuntu_22_04_cloud", false},
|
||||
{"max length", string(make([]byte, 255)), false}, // 255 chars
|
||||
|
||||
// Invalid
|
||||
{"empty", "", true},
|
||||
{"invalid template ID too small", "99", true},
|
||||
{"invalid template ID too large", "1000000000", true},
|
||||
{"invalid volid no storage", ":path", true},
|
||||
{"invalid volid no path", "storage:", true},
|
||||
{"too long name", string(make([]byte, 256)), true}, // 256 chars
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateImageSpec(tt.image)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ValidateImageSpec(%q) error = %v, wantErr %v", tt.image, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user