Place the forge's known host, SSH Host and git rewrite (issue 955 S3)
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -88,3 +89,89 @@ func TestManifestKeepsKeysAndRequiresForgeAccount(t *testing.T) {
|
||||
t.Errorf("provides = %v, want none (no ssh-key provision yet)", m.Provides)
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 955, area S3: the three files the forge account fills in — known_hosts, the forge's Host, git's rewrite.
|
||||
var sampleBound = map[string]string{
|
||||
"known_host": "[novox.internal]:222 ssh-ed25519 AAAAC3Nza",
|
||||
"ssh_host": "novox.internal",
|
||||
"ssh_port": "222",
|
||||
"ssh_base": "ssh://git@novox.internal:222/",
|
||||
"https_base": "https://git.novox.be/",
|
||||
}
|
||||
|
||||
// renderBound fills ${bound:forge-account:<key>} with the sample values, as the provisioner client does.
|
||||
func renderBound(t *testing.T, s string) string {
|
||||
t.Helper()
|
||||
for k, v := range sampleBound {
|
||||
s = strings.ReplaceAll(s, "${bound:forge-account:"+k+"}", v)
|
||||
}
|
||||
if strings.Contains(s, "${") {
|
||||
t.Errorf("unfilled placeholder in %q", s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func resourceByPath(t *testing.T, path string) map[string]any {
|
||||
t.Helper()
|
||||
raw, err := os.ReadFile(filepath.Join(moduleDir, "module.json"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var m struct {
|
||||
Resources []map[string]any `json:"resources"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, r := range m.Resources {
|
||||
if r["path"] == path {
|
||||
if r["owner"] != "${machine:account}" {
|
||||
t.Errorf("%s is owned by %v, not the machine's account", path, r["owner"])
|
||||
}
|
||||
return r
|
||||
}
|
||||
}
|
||||
t.Fatalf("no resource at %s", path)
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestForgeFilesRenderFromTheBoundValues(t *testing.T) {
|
||||
home := "${machine:account-home}"
|
||||
kh := resourceByPath(t, home+"/.ssh/known_hosts")
|
||||
if kh["into"] != "block" {
|
||||
t.Errorf("known_hosts is %v, want a block", kh["into"])
|
||||
}
|
||||
if got := strings.TrimSpace(renderBound(t, templateText(t, kh))); got != "[novox.internal]:222 ssh-ed25519 AAAAC3Nza" {
|
||||
t.Errorf("known_hosts block = %q", got)
|
||||
}
|
||||
|
||||
forge := resourceByPath(t, home+"/.ssh/config.d/10-forge")
|
||||
if forge["into"] != nil {
|
||||
t.Errorf("10-forge is a block, want the whole file")
|
||||
}
|
||||
want := "Host novox.internal\n Port 222\n User git\n IdentityFile ~/.ssh/mesh_ed25519\n IdentitiesOnly yes\n"
|
||||
if got := renderBound(t, templateText(t, forge)); got != want {
|
||||
t.Errorf("10-forge = %q, want %q", got, want)
|
||||
}
|
||||
|
||||
resourceByPath(t, home+"/.config/git") // the directory
|
||||
g := resourceByPath(t, home+"/.config/git/config")
|
||||
if g["into"] != "block" {
|
||||
t.Errorf("git config is %v, want a block", g["into"])
|
||||
}
|
||||
wantGit := "[url \"ssh://git@novox.internal:222/\"]\n\tinsteadOf = https://git.novox.be/\n"
|
||||
if got := renderBound(t, templateText(t, g)); got != wantGit {
|
||||
t.Errorf("git config block = %q, want %q", got, wantGit)
|
||||
}
|
||||
}
|
||||
|
||||
// The mesh's region in ~/.ssh/config brings in config.d/*, so 10-forge is read.
|
||||
func TestConfigIncludesTheDropInDirectory(t *testing.T) {
|
||||
raw, err := os.ReadFile(filepath.Join(moduleDir, "files", "config"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(raw), "Include ~/.ssh/config.d/*") {
|
||||
t.Errorf("files/config does not include config.d/*")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
Host ${bound:forge-account:ssh_host}
|
||||
Port ${bound:forge-account:ssh_port}
|
||||
User git
|
||||
IdentityFile ~/.ssh/mesh_ed25519
|
||||
IdentitiesOnly yes
|
||||
@@ -0,0 +1,2 @@
|
||||
[url "${bound:forge-account:ssh_base}"]
|
||||
insteadOf = ${bound:forge-account:https_base}
|
||||
@@ -0,0 +1 @@
|
||||
${bound:forge-account:known_host}
|
||||
@@ -51,6 +51,39 @@
|
||||
"into": "block",
|
||||
"at": "start",
|
||||
"template": "files/config"
|
||||
},
|
||||
{
|
||||
"id": "known-hosts",
|
||||
"type": "file",
|
||||
"path": "${machine:account-home}/.ssh/known_hosts",
|
||||
"owner": "${machine:account}",
|
||||
"mode": "0644",
|
||||
"into": "block",
|
||||
"template": "files/known_hosts"
|
||||
},
|
||||
{
|
||||
"id": "forge-host",
|
||||
"type": "file",
|
||||
"path": "${machine:account-home}/.ssh/config.d/10-forge",
|
||||
"owner": "${machine:account}",
|
||||
"mode": "0600",
|
||||
"template": "files/forge"
|
||||
},
|
||||
{
|
||||
"id": "git-config-dir",
|
||||
"type": "directory",
|
||||
"path": "${machine:account-home}/.config/git",
|
||||
"owner": "${machine:account}",
|
||||
"mode": "0755"
|
||||
},
|
||||
{
|
||||
"id": "git-config",
|
||||
"type": "file",
|
||||
"path": "${machine:account-home}/.config/git/config",
|
||||
"owner": "${machine:account}",
|
||||
"mode": "0644",
|
||||
"into": "block",
|
||||
"template": "files/gitconfig"
|
||||
}
|
||||
],
|
||||
"facts": {
|
||||
|
||||
Reference in New Issue
Block a user