94 lines
3.4 KiB
Go
94 lines
3.4 KiB
Go
package cloudflare
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestStoredTunnelStartsWithoutPublicIngress(t *testing.T) {
|
|
stored := StoredTunnel{Credentials: Credentials{AccountTag: "account", TunnelSecret: "secret", TunnelID: "tunnel"}, Config: NewConfig("tunnel")}
|
|
values, err := stored.Values()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, hasCredentials := values["credentials"]; !hasCredentials {
|
|
t.Fatal("new tunnel state did not use a simple credentials key")
|
|
}
|
|
parsed, present, err := ParseStoredTunnel(values)
|
|
if err != nil || !present || len(parsed.Config.Ingress) != 1 || parsed.Config.Ingress[0].Service != "http_status:404" {
|
|
t.Fatal("new tunnel state must contain only the terminal ingress rule")
|
|
}
|
|
legacy := map[string]string{"credentials.json": values["credentials"], "config.yml": values["config"]}
|
|
_, present, isLegacy, err := ParseStoredTunnelState(legacy)
|
|
if err != nil || !present || !isLegacy {
|
|
t.Fatal("valid dotted tunnel state was not recognized for migration")
|
|
}
|
|
}
|
|
|
|
func TestStoredTunnelRejectsLegacyOrPartialState(t *testing.T) {
|
|
for _, values := range []map[string]string{
|
|
{"token": "legacy-run-token"},
|
|
{"credentials.json": "{}"},
|
|
} {
|
|
if _, _, err := ParseStoredTunnel(values); err == nil {
|
|
t.Fatal("ambiguous tunnel state was accepted")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestReadCredentialsFileRequiresKnownFields(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "credentials.json")
|
|
raw := `{"AccountTag":"account","TunnelSecret":"secret","TunnelID":"tunnel"}`
|
|
for _, contents := range []string{
|
|
raw,
|
|
"apiVersion: v1\nkind: Secret\nstringData:\n credentials.json: |\n " + raw + "\n",
|
|
"apiVersion: v1\nkind: Secret\ndata:\n credentials.json: " + base64.StdEncoding.EncodeToString([]byte(raw)) + "\n",
|
|
} {
|
|
if err := os.WriteFile(path, []byte(contents), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
credentials, err := ReadCredentialsFile(path)
|
|
if err != nil || credentials.TunnelID != "tunnel" {
|
|
t.Fatal("supported credential file was not accepted")
|
|
}
|
|
}
|
|
if err := os.WriteFile(path, []byte(`{"AccountTag":"account","TunnelSecret":"secret","TunnelID":"tunnel","extra":"value"}`), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := ReadCredentialsFile(path); err == nil || err.Error() != "invalid Cloudflare credentials file" {
|
|
t.Fatal("credential file with unknown fields did not return a safe error")
|
|
}
|
|
if err := os.WriteFile(path, []byte("apiVersion: v1\nkind: Secret\ndata: {}\n"), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := ReadCredentialsFile(path); err == nil || err.Error() != "invalid Cloudflare credentials file" {
|
|
t.Fatal("Secret without credentials did not return a safe error")
|
|
}
|
|
}
|
|
|
|
func TestRouteConfigAddAndRemoveAreIdempotent(t *testing.T) {
|
|
config := NewConfig("tunnel")
|
|
route, err := NewRoute("app.example.test", "http://service.default.svc:8080")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
changed, err := config.AddRoute(route)
|
|
if err != nil || !changed || len(config.Ingress) != 2 {
|
|
t.Fatal("route was not added before the terminal ingress")
|
|
}
|
|
changed, err = config.AddRoute(route)
|
|
if err != nil || changed {
|
|
t.Fatal("matching route add was not idempotent")
|
|
}
|
|
changed, err = config.RemoveRoute(route)
|
|
if err != nil || !changed || len(config.Ingress) != 1 || config.Ingress[0].Service != "http_status:404" {
|
|
t.Fatal("route removal did not preserve the terminal ingress")
|
|
}
|
|
changed, err = config.RemoveRoute(route)
|
|
if err != nil || changed {
|
|
t.Fatal("matching route remove was not idempotent")
|
|
}
|
|
}
|