Hold ssh-client to its new shape: an include region first, the mesh's hosts in config.d (mesh-catalog #266)
This commit is contained in:
@@ -5,20 +5,24 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The ssh-client module, composed as a machine receives it (novox/hq to-be 29): every other node's
|
// The ssh-client module, composed as a machine receives it (novox/hq to-be 29, research 027/03): a
|
||||||
// Host block written into a marked region of the operator's ~/.ssh/config, owned by the account,
|
// region at the START of the operator's ~/.ssh/config that includes ~/.ssh/config.d/* — first,
|
||||||
// with ~/.ssh created 0700 — the operator's own config kept.
|
// because ssh takes the first value it finds for each option — and the mesh's Host blocks as the
|
||||||
|
// whole of ~/.ssh/config.d/00-mesh, every other node with its account. ~/.ssh and ~/.ssh/config.d
|
||||||
|
// are created 0700 and owned by the account; the operator's own config below the region is kept.
|
||||||
func TestSSHClientOwnsTheOperatorsSSHConfig(t *testing.T) {
|
func TestSSHClientOwnsTheOperatorsSSHConfig(t *testing.T) {
|
||||||
shelf := shelf(catalogueManifest(t, "ssh-client"))
|
shelf := shelf(catalogueManifest(t, "ssh-client"))
|
||||||
got, err := Resolve(shelf, []string{"ssh-client"},
|
got, err := Resolve(shelf, []string{"ssh-client"},
|
||||||
Node{Name: "homer", At: "homer.internal", Account: "jo"}, World{})
|
Node{Name: "homer", At: "homer.internal", Account: "jo", AccountHome: "/home/jo"}, World{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
names := map[string]string{"homer.internal": "10.10.0.1", "marge.internal": "10.10.0.2"}
|
names := map[string]string{"homer.internal": "10.10.0.1", "marge.internal": "10.10.0.2",
|
||||||
|
"bart.internal": "10.10.0.3"}
|
||||||
out, err := got.Declaration(Rendering{
|
out, err := got.Declaration(Rendering{
|
||||||
Names: names, Machines: names, Accounts: map[string]string{"homer": "jo", "marge": "jo"},
|
Names: names, Machines: names,
|
||||||
Suffix: "internal",
|
Accounts: map[string]string{"homer": "jo", "marge": "jo", "bart": "op"},
|
||||||
|
Suffix: "internal",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -28,19 +32,39 @@ func TestSSHClientOwnsTheOperatorsSSHConfig(t *testing.T) {
|
|||||||
by[r["id"].(string)] = r
|
by[r["id"].(string)] = r
|
||||||
}
|
}
|
||||||
|
|
||||||
dir := by["ssh-client.ssh-dir"]
|
for id, path := range map[string]string{
|
||||||
if dir == nil || dir["path"] != "/home/jo/.ssh" || dir["owner"] != "jo" || dir["mode"] != "0700" {
|
"ssh-client.ssh-dir": "/home/jo/.ssh", "ssh-client.config-d": "/home/jo/.ssh/config.d"} {
|
||||||
t.Fatalf("~/.ssh is not created 0700 owned by the account: %v", dir)
|
dir := by[id]
|
||||||
|
if dir == nil || dir["type"] != "directory" || dir["path"] != path || dir["owner"] != "jo" || dir["mode"] != "0700" {
|
||||||
|
t.Fatalf("%s is not created 0700 owned by the account: %v", path, dir)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cfg := by["ssh-client.fact-ssh-config"]
|
|
||||||
if cfg == nil || cfg["path"] != "/home/jo/.ssh/config" || cfg["owner"] != "jo" || cfg["into"] != "block" {
|
cfg := by["ssh-client.config"]
|
||||||
t.Fatalf("the ssh config is not written into the operator's ~/.ssh/config as a region: %v", cfg)
|
if cfg == nil || cfg["path"] != "/home/jo/.ssh/config" || cfg["owner"] != "jo" ||
|
||||||
|
cfg["into"] != "block" || cfg["at"] != "start" {
|
||||||
|
t.Fatalf("the mesh's region is not the first thing in the operator's ~/.ssh/config: %v", cfg)
|
||||||
}
|
}
|
||||||
body := cfg["content"].(string)
|
if body := cfg["content"].(string); !strings.Contains(body, "\nInclude ~/.ssh/config.d/*\n") || strings.Contains(body, "\nHost ") {
|
||||||
if !strings.Contains(body, "Host marge marge.internal") || !strings.Contains(body, "User jo") {
|
t.Fatalf("the region does not just include config.d:\n%s", body)
|
||||||
t.Fatalf("the config does not name the peer node and its account:\n%s", body)
|
}
|
||||||
|
|
||||||
|
var hosts map[string]any
|
||||||
|
for _, r := range out {
|
||||||
|
if r["path"] == "/home/jo/.ssh/config.d/00-mesh" {
|
||||||
|
hosts = r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if hosts == nil || hosts["type"] != "file" || hosts["into"] != nil {
|
||||||
|
t.Fatalf("the mesh's hosts are not the whole of ~/.ssh/config.d/00-mesh: %v", hosts)
|
||||||
|
}
|
||||||
|
body := hosts["content"].(string)
|
||||||
|
for _, want := range []string{"Host marge marge.internal", "Host bart bart.internal", "User jo", "User op"} {
|
||||||
|
if !strings.Contains(body, want) {
|
||||||
|
t.Fatalf("00-mesh does not say %q — every other node with its account:\n%s", want, body)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if strings.Contains(body, "Host homer ") {
|
if strings.Contains(body, "Host homer ") {
|
||||||
t.Fatalf("the config names the machine itself, not only its peers:\n%s", body)
|
t.Fatalf("00-mesh names the machine itself, not only its peers:\n%s", body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user