1be7cf2b7f
CI / test (push) Successful in 1m41s
Implements the narrowed Stage 1 scope from ROADMAP.md, against the bootstrap-flow fix from DESIGN.md §4.1/§6 (the earlier self-registration flow couldn't work unauthenticated against terdut-server's real AuthMiddleware -- see that commit for the full trace). - api/v1alpha1: TerdutServer with spec.endpoint + spec.credentialsSecretRef + spec.allowedTeams (image/replicas/networking/database deferred to Stage 5, per DESIGN.md's own narrowing). SecretKeyRef has no namespace field -- always the operator's own, by construction. - internal/controller: TerdutServerReconciler implements exactly the bring-your-own path -- adopt spec.credentialsSecretRef if the Secret exists and has data under the given key, probe GET /api/version as a reachability check, set Ready/Bootstrapped conditions accordingly. Self-registration (the /api/bootstrap race) is not implemented; unset spec.credentialsSecretRef reports Ready: False, reason: CredentialsSecretRefRequired, not an attempt at a flow that would fail unauthenticated anyway. No finalizer: this stage creates nothing server-side and adopts rather than generates its Secret, so there's nothing to clean up on delete yet. - internal/tdclient: minimal terdut-server API client (Version only, the one call this stage needs), styled after terdut-tui's own internal/api/client.go per terdut/CLAUDE.md's mirroring convention. - Tests: envtest suite covering all four not-ready paths plus the happy path (fake terdut-server via httptest.Server, per DESIGN.md §11), and a focused unit suite for tdclient. 75.6%/82.4% coverage. - Event recording uses the new events.k8s.io/v1 recorder API (mgr.GetEventRecorder), not the deprecated GetEventRecorderFor -- caught by golangci-lint's staticcheck before it shipped. Verified locally: make fmt lint test build all clean, 0 lint issues, all specs pass.
101 lines
2.8 KiB
Go
101 lines
2.8 KiB
Go
package controller
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
|
|
"k8s.io/client-go/kubernetes/scheme"
|
|
"k8s.io/client-go/rest"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
|
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
|
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
|
|
|
terdutv1alpha1 "git.ryuvia.com/niklas/terdut-operator/api/v1alpha1"
|
|
// +kubebuilder:scaffold:imports
|
|
)
|
|
|
|
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
|
|
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
|
|
|
|
var (
|
|
ctx context.Context
|
|
cancel context.CancelFunc
|
|
testEnv *envtest.Environment
|
|
cfg *rest.Config
|
|
k8sClient client.Client
|
|
)
|
|
|
|
func TestControllers(t *testing.T) {
|
|
RegisterFailHandler(Fail)
|
|
|
|
RunSpecs(t, "Controller Suite")
|
|
}
|
|
|
|
var _ = BeforeSuite(func() {
|
|
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
|
|
|
|
ctx, cancel = context.WithCancel(context.TODO())
|
|
|
|
var err error
|
|
err = terdutv1alpha1.AddToScheme(scheme.Scheme)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
// +kubebuilder:scaffold:scheme
|
|
|
|
By("bootstrapping test environment")
|
|
testEnv = &envtest.Environment{
|
|
CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")},
|
|
ErrorIfCRDPathMissing: true,
|
|
}
|
|
|
|
// Retrieve the first found binary directory to allow running tests from IDEs
|
|
if getFirstFoundEnvTestBinaryDir() != "" {
|
|
testEnv.BinaryAssetsDirectory = getFirstFoundEnvTestBinaryDir()
|
|
}
|
|
|
|
// cfg is defined in this file globally.
|
|
cfg, err = testEnv.Start()
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(cfg).NotTo(BeNil())
|
|
|
|
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(k8sClient).NotTo(BeNil())
|
|
})
|
|
|
|
var _ = AfterSuite(func() {
|
|
By("tearing down the test environment")
|
|
cancel()
|
|
err := testEnv.Stop()
|
|
Expect(err).NotTo(HaveOccurred())
|
|
})
|
|
|
|
// getFirstFoundEnvTestBinaryDir locates the first binary in the specified path.
|
|
// ENVTEST-based tests depend on specific binaries, usually located in paths set by
|
|
// controller-runtime. When running tests directly (e.g., via an IDE) without using
|
|
// Makefile targets, the 'BinaryAssetsDirectory' must be explicitly configured.
|
|
//
|
|
// This function streamlines the process by finding the required binaries, similar to
|
|
// setting the 'KUBEBUILDER_ASSETS' environment variable. To ensure the binaries are
|
|
// properly set up, run 'make setup-envtest' beforehand.
|
|
func getFirstFoundEnvTestBinaryDir() string {
|
|
basePath := filepath.Join("..", "..", "bin", "k8s")
|
|
entries, err := os.ReadDir(basePath)
|
|
if err != nil {
|
|
logf.Log.Error(err, "Failed to read directory", "path", basePath)
|
|
return ""
|
|
}
|
|
for _, entry := range entries {
|
|
if entry.IsDir() {
|
|
return filepath.Join(basePath, entry.Name())
|
|
}
|
|
}
|
|
return ""
|
|
}
|