373d21a744
Postgres-backed External Node Classifier for Puppet, replacing Cobbler. - encapi HTTP server (chi + pgx): read/write API + two ENC document shapes (reshaped for the exec terminus; cobbler-wire for enc_direct_facts.rb) - encapi-cli: classify/node/role/status CRUD + import-cobbler seeder - pkg/client Go SDK; unit tests across all packages (DB via testcontainers) - Dockerfile (distroless), Makefile, nfpm RPM (encapi-cli + encapi-enc wrapper), Woodpecker CI, docs/cutover.md
78 lines
2.1 KiB
Go
78 lines
2.1 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"git.unkin.net/unkin/encapi/pkg/models"
|
|
)
|
|
|
|
func TestPutNodeSendsTokenAndBody(t *testing.T) {
|
|
var gotAuth, gotMethod, gotPath string
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
gotAuth = r.Header.Get("Authorization")
|
|
gotMethod = r.Method
|
|
gotPath = r.URL.Path
|
|
_, _ = w.Write([]byte(`{"certname":"h1","role":"roles::base","environment":"testing"}`))
|
|
}))
|
|
defer srv.Close()
|
|
|
|
c := New(srv.URL, "tok")
|
|
n, err := c.PutNode(context.Background(), &models.Node{Certname: "h1", Role: "roles::base", Environment: "testing"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if gotAuth != "Bearer tok" {
|
|
t.Errorf("auth = %q", gotAuth)
|
|
}
|
|
if gotMethod != http.MethodPut || gotPath != "/api/v1/nodes/h1" {
|
|
t.Errorf("%s %s", gotMethod, gotPath)
|
|
}
|
|
if n.Role != "roles::base" {
|
|
t.Errorf("node = %+v", n)
|
|
}
|
|
}
|
|
|
|
func TestGetRoleEscapesColons(t *testing.T) {
|
|
var gotPath string
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
gotPath = r.URL.EscapedPath()
|
|
_, _ = w.Write([]byte(`{"name":"roles::infra::x"}`))
|
|
}))
|
|
defer srv.Close()
|
|
if _, err := New(srv.URL, "").GetRole(context.Background(), "roles::infra::x"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if gotPath != "/api/v1/roles/roles::infra::x" {
|
|
t.Errorf("path = %q", gotPath)
|
|
}
|
|
}
|
|
|
|
func TestErrorMapping(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
_, _ = w.Write([]byte(`{"error":"not found"}`))
|
|
}))
|
|
defer srv.Close()
|
|
_, err := New(srv.URL, "").GetNode(context.Background(), "ghost")
|
|
if err == nil || !NotFound(err) {
|
|
t.Fatalf("err = %v, want NotFound", err)
|
|
}
|
|
}
|
|
|
|
func TestENCReturnsRawYAML(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
_, _ = w.Write([]byte("classes:\n- roles::base\n"))
|
|
}))
|
|
defer srv.Close()
|
|
b, err := New(srv.URL, "").ENC(context.Background(), "h1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if string(b) != "classes:\n- roles::base\n" {
|
|
t.Errorf("enc = %q", b)
|
|
}
|
|
}
|