- Created T026-practical-test task.yaml for MVP smoke testing - Added k8shost-server to flake.nix (packages, apps, overlays) - Staged all workspace directories for nix flake build - Updated flake.nix shellHook to include k8shost Resolves: T026.S1 blocker (R8 - nix submodule visibility)
165 lines
5.9 KiB
Rust
165 lines
5.9 KiB
Rust
//! Integration test for reverse DNS pattern-based PTR generation
|
|
use std::net::{IpAddr, Ipv4Addr};
|
|
use flashdns_types::ReverseZone;
|
|
use std::sync::Arc;
|
|
use tokio;
|
|
|
|
#[tokio::test]
|
|
#[ignore] // Requires running servers
|
|
async fn test_reverse_dns_lifecycle() {
|
|
// Test comprehensive reverse DNS lifecycle:
|
|
// 1. Create ReverseZone via metadata store
|
|
// 2. Query PTR via DNS handler pattern matching
|
|
// 3. Verify response with pattern substitution
|
|
// 4. Delete zone
|
|
// 5. Verify PTR query fails after deletion
|
|
|
|
// Setup: Create metadata store
|
|
let metadata = Arc::new(
|
|
flashdns_server::metadata::DnsMetadataStore::new_in_memory()
|
|
);
|
|
|
|
// Step 1: Create reverse zone for 10.0.0.0/8
|
|
let zone = ReverseZone {
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
org_id: "test-org".to_string(),
|
|
project_id: Some("test-project".to_string()),
|
|
cidr: "10.0.0.0/8".to_string(),
|
|
arpa_zone: "10.in-addr.arpa.".to_string(), // Will be auto-generated
|
|
ptr_pattern: "{4}-{3}-{2}-{1}.hosts.cloud.local.".to_string(),
|
|
ttl: 3600,
|
|
created_at: chrono::Utc::now().timestamp() as u64,
|
|
updated_at: chrono::Utc::now().timestamp() as u64,
|
|
};
|
|
|
|
metadata.create_reverse_zone(zone.clone()).await.unwrap();
|
|
|
|
// Step 2: Simulate PTR query for 10.1.2.3
|
|
// Note: This requires DNS handler integration, which we'll test via pattern utilities
|
|
use flashdns_server::dns::ptr_patterns::{parse_ptr_query_to_ip, apply_pattern};
|
|
|
|
let ptr_query = "3.2.1.10.in-addr.arpa.";
|
|
let ip = parse_ptr_query_to_ip(ptr_query).unwrap();
|
|
assert_eq!(ip, IpAddr::V4(Ipv4Addr::new(10, 1, 2, 3)));
|
|
|
|
// Step 3: Apply pattern substitution
|
|
let result = apply_pattern(&zone.ptr_pattern, ip);
|
|
assert_eq!(result, "3-2-1-10.hosts.cloud.local.");
|
|
|
|
// Step 4: Verify zone can be retrieved
|
|
let retrieved = metadata.get_reverse_zone(&zone.id).await.unwrap();
|
|
assert!(retrieved.is_some());
|
|
let retrieved_zone = retrieved.unwrap();
|
|
assert_eq!(retrieved_zone.cidr, "10.0.0.0/8");
|
|
assert_eq!(retrieved_zone.ptr_pattern, "{4}-{3}-{2}-{1}.hosts.cloud.local.");
|
|
|
|
// Step 5: Delete zone
|
|
metadata.delete_reverse_zone(&zone).await.unwrap();
|
|
|
|
// Step 6: Verify zone no longer exists
|
|
let deleted_check = metadata.get_reverse_zone(&zone.id).await.unwrap();
|
|
assert!(deleted_check.is_none());
|
|
|
|
println!("✓ Reverse DNS lifecycle test passed");
|
|
}
|
|
|
|
#[tokio::test]
|
|
#[ignore]
|
|
async fn test_reverse_dns_ipv6() {
|
|
// Test IPv6 reverse DNS pattern
|
|
use std::net::Ipv6Addr;
|
|
use flashdns_server::dns::ptr_patterns::apply_pattern;
|
|
|
|
let pattern = "v6-{short}.example.com.";
|
|
let ip = IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
|
|
|
|
let result = apply_pattern(pattern, ip);
|
|
assert_eq!(result, "v6-2001-db8--1.example.com.");
|
|
|
|
println!("✓ IPv6 reverse DNS pattern test passed");
|
|
}
|
|
|
|
#[tokio::test]
|
|
#[ignore]
|
|
async fn test_multiple_reverse_zones_longest_prefix() {
|
|
// Test longest prefix matching
|
|
let metadata = Arc::new(
|
|
flashdns_server::metadata::DnsMetadataStore::new_in_memory()
|
|
);
|
|
|
|
// Create /8 zone
|
|
let zone_8 = ReverseZone {
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
org_id: "test-org".to_string(),
|
|
project_id: Some("test-project".to_string()),
|
|
cidr: "192.0.0.0/8".to_string(),
|
|
arpa_zone: "192.in-addr.arpa.".to_string(),
|
|
ptr_pattern: "host-{ip}-slash8.example.com.".to_string(),
|
|
ttl: 3600,
|
|
created_at: chrono::Utc::now().timestamp() as u64,
|
|
updated_at: chrono::Utc::now().timestamp() as u64,
|
|
};
|
|
|
|
// Create /16 zone (more specific)
|
|
let zone_16 = ReverseZone {
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
org_id: "test-org".to_string(),
|
|
project_id: Some("test-project".to_string()),
|
|
cidr: "192.168.0.0/16".to_string(),
|
|
arpa_zone: "168.192.in-addr.arpa.".to_string(),
|
|
ptr_pattern: "host-{ip}-slash16.example.com.".to_string(),
|
|
ttl: 3600,
|
|
created_at: chrono::Utc::now().timestamp() as u64,
|
|
updated_at: chrono::Utc::now().timestamp() as u64,
|
|
};
|
|
|
|
// Create /24 zone (most specific)
|
|
let zone_24 = ReverseZone {
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
org_id: "test-org".to_string(),
|
|
project_id: Some("test-project".to_string()),
|
|
cidr: "192.168.1.0/24".to_string(),
|
|
arpa_zone: "1.168.192.in-addr.arpa.".to_string(),
|
|
ptr_pattern: "host-{ip}-slash24.example.com.".to_string(),
|
|
ttl: 3600,
|
|
created_at: chrono::Utc::now().timestamp() as u64,
|
|
updated_at: chrono::Utc::now().timestamp() as u64,
|
|
};
|
|
|
|
metadata.create_reverse_zone(zone_8.clone()).await.unwrap();
|
|
metadata.create_reverse_zone(zone_16.clone()).await.unwrap();
|
|
metadata.create_reverse_zone(zone_24.clone()).await.unwrap();
|
|
|
|
// Query IP that matches all three zones
|
|
// Longest prefix (most specific) should win: /24 > /16 > /8
|
|
let _ip = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 5));
|
|
|
|
// Note: Actual longest-prefix matching is in DNS handler
|
|
// Here we verify all zones are stored correctly
|
|
let all_zones = metadata.list_reverse_zones("test-org", Some("test-project")).await.unwrap();
|
|
assert_eq!(all_zones.len(), 3);
|
|
|
|
println!("✓ Multiple reverse zones test passed");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_pattern_substitution_variations() {
|
|
// Test various pattern substitution formats
|
|
use flashdns_server::dns::ptr_patterns::apply_pattern;
|
|
|
|
let ip = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 5));
|
|
|
|
// Test individual octets
|
|
assert_eq!(apply_pattern("{1}.{2}.{3}.{4}", ip), "192.168.1.5");
|
|
|
|
// Test reversed octets
|
|
assert_eq!(apply_pattern("{4}.{3}.{2}.{1}", ip), "5.1.168.192");
|
|
|
|
// Test dashed IP
|
|
assert_eq!(apply_pattern("{ip}", ip), "192-168-1-5");
|
|
|
|
// Test combined pattern
|
|
assert_eq!(apply_pattern("server-{4}-subnet-{3}.dc.example.com.", ip), "server-5-subnet-1.dc.example.com.");
|
|
|
|
println!("✓ Pattern substitution variations test passed");
|
|
}
|