- new towerops_check resource supporting HTTP, TCP, DNS, and ping checks - flat schema with type-specific fields (url, host, port, hostname, etc.) - client CRUD methods for /api/v1/checks endpoints - resource documentation, examples, and provider index updated - acceptance tests for all check types, update, import, and error handling
756 lines
21 KiB
Go
756 lines
21 KiB
Go
package provider
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"regexp"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
|
)
|
|
|
|
func TestAccCheckResource_http(t *testing.T) {
|
|
var checkID string
|
|
var mu sync.Mutex
|
|
enabled := true
|
|
interval := 60
|
|
timeout := 5000
|
|
retry := 30
|
|
maxAttempts := 3
|
|
currentState := 3
|
|
stateType := "soft"
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
switch {
|
|
case r.Method == http.MethodPost && r.URL.Path == "/api/v1/checks":
|
|
checkID = "test-http-check-id"
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(Check{
|
|
ID: checkID,
|
|
Name: "Web Health",
|
|
CheckType: "http",
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"url": "https://example.com/health",
|
|
"method": "GET",
|
|
"expected_status": 200,
|
|
"verify_ssl": true,
|
|
"follow_redirects": true,
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
})
|
|
|
|
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(Check{
|
|
ID: checkID,
|
|
Name: "Web Health",
|
|
CheckType: "http",
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"url": "https://example.com/health",
|
|
"method": "GET",
|
|
"expected_status": 200,
|
|
"verify_ssl": true,
|
|
"follow_redirects": true,
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
})
|
|
|
|
case r.Method == http.MethodDelete && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
default:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(server.URL),
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccCheckResourceHTTP(server.URL),
|
|
Check: resource.ComposeAggregateTestCheckFunc(
|
|
resource.TestCheckResourceAttr("towerops_check.test", "name", "Web Health"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "check_type", "http"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "url", "https://example.com/health"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "expected_status", "200"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "enabled", "true"),
|
|
resource.TestCheckResourceAttrSet("towerops_check.test", "id"),
|
|
resource.TestCheckResourceAttrSet("towerops_check.test", "inserted_at"),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccCheckResource_tcp(t *testing.T) {
|
|
var checkID string
|
|
var mu sync.Mutex
|
|
enabled := true
|
|
interval := 60
|
|
timeout := 5000
|
|
retry := 30
|
|
maxAttempts := 3
|
|
currentState := 3
|
|
stateType := "soft"
|
|
deviceID := "device-123"
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
switch {
|
|
case r.Method == http.MethodPost && r.URL.Path == "/api/v1/checks":
|
|
checkID = "test-tcp-check-id"
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(Check{
|
|
ID: checkID,
|
|
Name: "MySQL Port",
|
|
CheckType: "tcp",
|
|
DeviceID: &deviceID,
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"host": "10.0.0.5",
|
|
"port": 3306,
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
})
|
|
|
|
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(Check{
|
|
ID: checkID,
|
|
Name: "MySQL Port",
|
|
CheckType: "tcp",
|
|
DeviceID: &deviceID,
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"host": "10.0.0.5",
|
|
"port": 3306,
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
})
|
|
|
|
case r.Method == http.MethodDelete && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
default:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(server.URL),
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccCheckResourceTCP(server.URL),
|
|
Check: resource.ComposeAggregateTestCheckFunc(
|
|
resource.TestCheckResourceAttr("towerops_check.test", "name", "MySQL Port"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "check_type", "tcp"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "host", "10.0.0.5"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "port", "3306"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "device_id", "device-123"),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccCheckResource_dns(t *testing.T) {
|
|
var checkID string
|
|
var mu sync.Mutex
|
|
enabled := true
|
|
interval := 60
|
|
timeout := 5000
|
|
retry := 30
|
|
maxAttempts := 3
|
|
currentState := 3
|
|
stateType := "soft"
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
switch {
|
|
case r.Method == http.MethodPost && r.URL.Path == "/api/v1/checks":
|
|
checkID = "test-dns-check-id"
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(Check{
|
|
ID: checkID,
|
|
Name: "DNS Resolution",
|
|
CheckType: "dns",
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"hostname": "google.com",
|
|
"server": "8.8.8.8",
|
|
"record_type": "A",
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
})
|
|
|
|
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(Check{
|
|
ID: checkID,
|
|
Name: "DNS Resolution",
|
|
CheckType: "dns",
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"hostname": "google.com",
|
|
"server": "8.8.8.8",
|
|
"record_type": "A",
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
})
|
|
|
|
case r.Method == http.MethodDelete && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
default:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(server.URL),
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccCheckResourceDNS(server.URL),
|
|
Check: resource.ComposeAggregateTestCheckFunc(
|
|
resource.TestCheckResourceAttr("towerops_check.test", "name", "DNS Resolution"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "check_type", "dns"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "hostname", "google.com"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "dns_server", "8.8.8.8"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "record_type", "A"),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccCheckResource_ping(t *testing.T) {
|
|
var checkID string
|
|
var mu sync.Mutex
|
|
enabled := true
|
|
interval := 60
|
|
timeout := 5000
|
|
retry := 30
|
|
maxAttempts := 3
|
|
currentState := 3
|
|
stateType := "soft"
|
|
deviceID := "device-gw"
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
switch {
|
|
case r.Method == http.MethodPost && r.URL.Path == "/api/v1/checks":
|
|
checkID = "test-ping-check-id"
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(Check{
|
|
ID: checkID,
|
|
Name: "Gateway Ping",
|
|
CheckType: "ping",
|
|
DeviceID: &deviceID,
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"host": "10.0.0.1",
|
|
"count": 3,
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
})
|
|
|
|
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(Check{
|
|
ID: checkID,
|
|
Name: "Gateway Ping",
|
|
CheckType: "ping",
|
|
DeviceID: &deviceID,
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"host": "10.0.0.1",
|
|
"count": 3,
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
})
|
|
|
|
case r.Method == http.MethodDelete && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
default:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(server.URL),
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccCheckResourcePing(server.URL),
|
|
Check: resource.ComposeAggregateTestCheckFunc(
|
|
resource.TestCheckResourceAttr("towerops_check.test", "name", "Gateway Ping"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "check_type", "ping"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "host", "10.0.0.1"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "ping_count", "3"),
|
|
resource.TestCheckResourceAttr("towerops_check.test", "device_id", "device-gw"),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccCheckResource_update(t *testing.T) {
|
|
var checkID string
|
|
var currentName string
|
|
var mu sync.Mutex
|
|
enabled := true
|
|
interval := 60
|
|
timeout := 5000
|
|
retry := 30
|
|
maxAttempts := 3
|
|
currentState := 3
|
|
stateType := "soft"
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
switch {
|
|
case r.Method == http.MethodPost && r.URL.Path == "/api/v1/checks":
|
|
checkID = "test-update-check-id"
|
|
currentName = "Original"
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(Check{
|
|
ID: checkID,
|
|
Name: currentName,
|
|
CheckType: "http",
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"url": "https://example.com",
|
|
"method": "GET",
|
|
"expected_status": 200,
|
|
"verify_ssl": true,
|
|
"follow_redirects": true,
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
})
|
|
|
|
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(Check{
|
|
ID: checkID,
|
|
Name: currentName,
|
|
CheckType: "http",
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"url": "https://example.com",
|
|
"method": "GET",
|
|
"expected_status": 200,
|
|
"verify_ssl": true,
|
|
"follow_redirects": true,
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
})
|
|
|
|
case r.Method == http.MethodPatch && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
var body map[string]Check
|
|
json.NewDecoder(r.Body).Decode(&body)
|
|
currentName = body["check"].Name
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(Check{
|
|
ID: checkID,
|
|
Name: currentName,
|
|
CheckType: "http",
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"url": "https://example.com",
|
|
"method": "GET",
|
|
"expected_status": 200,
|
|
"verify_ssl": true,
|
|
"follow_redirects": true,
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
})
|
|
|
|
case r.Method == http.MethodDelete && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
default:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(server.URL),
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccCheckResourceHTTPNamed(server.URL, "Original"),
|
|
Check: resource.ComposeAggregateTestCheckFunc(
|
|
resource.TestCheckResourceAttr("towerops_check.test", "name", "Original"),
|
|
),
|
|
},
|
|
{
|
|
Config: testAccCheckResourceHTTPNamed(server.URL, "Updated"),
|
|
Check: resource.ComposeAggregateTestCheckFunc(
|
|
resource.TestCheckResourceAttr("towerops_check.test", "name", "Updated"),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccCheckResource_recreateOn404(t *testing.T) {
|
|
var checkID string
|
|
var checkDeleted bool
|
|
var mu sync.Mutex
|
|
enabled := true
|
|
interval := 60
|
|
timeout := 5000
|
|
retry := 30
|
|
maxAttempts := 3
|
|
currentState := 3
|
|
stateType := "soft"
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
checkResp := Check{
|
|
ID: "new-check-id",
|
|
Name: "Web Health",
|
|
CheckType: "http",
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"url": "https://example.com/health",
|
|
"method": "GET",
|
|
"expected_status": 200,
|
|
"verify_ssl": true,
|
|
"follow_redirects": true,
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
}
|
|
|
|
switch {
|
|
case r.Method == http.MethodPost && r.URL.Path == "/api/v1/checks":
|
|
checkID = "new-check-id"
|
|
checkDeleted = false
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(checkResp)
|
|
|
|
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
if checkDeleted {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
w.Write([]byte(`{"error": "check not found"}`))
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(checkResp)
|
|
|
|
case r.Method == http.MethodPatch && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
if checkDeleted {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
w.Write([]byte(`{"error": "check not found"}`))
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(checkResp)
|
|
|
|
case r.Method == http.MethodDelete && r.URL.Path == "/api/v1/checks/"+checkID:
|
|
checkDeleted = true
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
default:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(server.URL),
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccCheckResourceHTTP(server.URL),
|
|
Check: resource.ComposeAggregateTestCheckFunc(
|
|
resource.TestCheckResourceAttr("towerops_check.test", "name", "Web Health"),
|
|
),
|
|
},
|
|
{
|
|
PreConfig: func() {
|
|
mu.Lock()
|
|
checkDeleted = true
|
|
mu.Unlock()
|
|
},
|
|
Config: testAccCheckResourceHTTP(server.URL),
|
|
Check: resource.ComposeAggregateTestCheckFunc(
|
|
resource.TestCheckResourceAttrSet("towerops_check.test", "id"),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccCheckResource_importState(t *testing.T) {
|
|
var checkID string
|
|
var mu sync.Mutex
|
|
enabled := true
|
|
interval := 60
|
|
timeout := 5000
|
|
retry := 30
|
|
maxAttempts := 3
|
|
currentState := 3
|
|
stateType := "soft"
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
checkResp := Check{
|
|
ID: "imported-check-id",
|
|
Name: "Web Health",
|
|
CheckType: "http",
|
|
Enabled: &enabled,
|
|
IntervalSeconds: &interval,
|
|
TimeoutMs: &timeout,
|
|
RetryIntervalSeconds: &retry,
|
|
MaxCheckAttempts: &maxAttempts,
|
|
CurrentState: ¤tState,
|
|
CurrentStateType: &stateType,
|
|
Config: map[string]any{
|
|
"url": "https://example.com/health",
|
|
"method": "GET",
|
|
"expected_status": 200,
|
|
"verify_ssl": true,
|
|
"follow_redirects": true,
|
|
},
|
|
InsertedAt: "2024-01-01T00:00:00Z",
|
|
}
|
|
|
|
switch {
|
|
case r.Method == http.MethodPost && r.URL.Path == "/api/v1/checks":
|
|
checkID = "imported-check-id"
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(checkResp)
|
|
|
|
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/checks/imported-check-id":
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(checkResp)
|
|
|
|
case r.Method == http.MethodDelete && r.URL.Path == "/api/v1/checks/imported-check-id":
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
default:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
_ = checkID
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(server.URL),
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccCheckResourceHTTP(server.URL),
|
|
},
|
|
{
|
|
ResourceName: "towerops_check.test",
|
|
ImportState: true,
|
|
ImportStateVerify: true,
|
|
ImportStateVerifyIgnore: []string{"ping_count", "record_type"},
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccCheckResource_createError(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method == http.MethodPost && r.URL.Path == "/api/v1/checks" {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
w.Write([]byte(`{"error": "name is required"}`))
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}))
|
|
defer server.Close()
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(server.URL),
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccCheckResourceHTTP(server.URL),
|
|
ExpectError: regexp.MustCompile(`Failed to create check`),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
// HCL config helpers
|
|
|
|
func testAccCheckResourceHTTP(apiURL string) string {
|
|
return fmt.Sprintf(`
|
|
provider "towerops" {
|
|
token = "test-token"
|
|
api_url = %q
|
|
}
|
|
|
|
resource "towerops_check" "test" {
|
|
name = "Web Health"
|
|
check_type = "http"
|
|
url = "https://example.com/health"
|
|
expected_status = 200
|
|
}
|
|
`, apiURL)
|
|
}
|
|
|
|
func testAccCheckResourceHTTPNamed(apiURL, name string) string {
|
|
return fmt.Sprintf(`
|
|
provider "towerops" {
|
|
token = "test-token"
|
|
api_url = %q
|
|
}
|
|
|
|
resource "towerops_check" "test" {
|
|
name = %q
|
|
check_type = "http"
|
|
url = "https://example.com"
|
|
expected_status = 200
|
|
}
|
|
`, apiURL, name)
|
|
}
|
|
|
|
func testAccCheckResourceTCP(apiURL string) string {
|
|
return fmt.Sprintf(`
|
|
provider "towerops" {
|
|
token = "test-token"
|
|
api_url = %q
|
|
}
|
|
|
|
resource "towerops_check" "test" {
|
|
name = "MySQL Port"
|
|
check_type = "tcp"
|
|
device_id = "device-123"
|
|
host = "10.0.0.5"
|
|
port = 3306
|
|
}
|
|
`, apiURL)
|
|
}
|
|
|
|
func testAccCheckResourceDNS(apiURL string) string {
|
|
return fmt.Sprintf(`
|
|
provider "towerops" {
|
|
token = "test-token"
|
|
api_url = %q
|
|
}
|
|
|
|
resource "towerops_check" "test" {
|
|
name = "DNS Resolution"
|
|
check_type = "dns"
|
|
hostname = "google.com"
|
|
dns_server = "8.8.8.8"
|
|
record_type = "A"
|
|
}
|
|
`, apiURL)
|
|
}
|
|
|
|
func testAccCheckResourcePing(apiURL string) string {
|
|
return fmt.Sprintf(`
|
|
provider "towerops" {
|
|
token = "test-token"
|
|
api_url = %q
|
|
}
|
|
|
|
resource "towerops_check" "test" {
|
|
name = "Gateway Ping"
|
|
check_type = "ping"
|
|
device_id = "device-gw"
|
|
host = "10.0.0.1"
|
|
ping_count = 3
|
|
}
|
|
`, apiURL)
|
|
}
|