security: use Vault injection for remote worker credentials
This commit is contained in:
parent
40618a90e8
commit
b42cf9564f
@ -12,7 +12,13 @@ import (
|
|||||||
"metis/pkg/inventory"
|
"metis/pkg/inventory"
|
||||||
)
|
)
|
||||||
|
|
||||||
const hostTmpDevicePath = "hosttmp:///tmp"
|
const (
|
||||||
|
hostTmpDevicePath = "hosttmp:///tmp"
|
||||||
|
vaultRoleMaintenance = "maintenance"
|
||||||
|
vaultRuntimeSecretPath = "kv/data/atlas/maintenance/metis-runtime"
|
||||||
|
vaultHarborSecretPath = "kv/data/atlas/harbor/harbor-core"
|
||||||
|
vaultSSHKeysSecretPath = "kv/data/atlas/maintenance/metis-ssh-keys"
|
||||||
|
)
|
||||||
|
|
||||||
func (a *App) ListDevices(host string) ([]Device, error) {
|
func (a *App) ListDevices(host string) ([]Device, error) {
|
||||||
return a.cachedDevices(host)
|
return a.cachedDevices(host)
|
||||||
@ -450,6 +456,7 @@ func (a *App) remoteBuildPodSpec(name, host, image, node, artifactRef, buildTag
|
|||||||
"name": name,
|
"name": name,
|
||||||
"namespace": a.settings.Namespace,
|
"namespace": a.settings.Namespace,
|
||||||
"labels": map[string]string{"app": "metis-remote", "metis-run": "build"},
|
"labels": map[string]string{"app": "metis-remote", "metis-run": "build"},
|
||||||
|
"annotations": vaultRuntimeAnnotations(true),
|
||||||
},
|
},
|
||||||
"spec": map[string]any{
|
"spec": map[string]any{
|
||||||
"restartPolicy": "Never",
|
"restartPolicy": "Never",
|
||||||
@ -462,8 +469,11 @@ func (a *App) remoteBuildPodSpec(name, host, image, node, artifactRef, buildTag
|
|||||||
"name": "remote-build",
|
"name": "remote-build",
|
||||||
"image": image,
|
"image": image,
|
||||||
"imagePullPolicy": "Always",
|
"imagePullPolicy": "Always",
|
||||||
"command": []string{
|
"command": []string{"/bin/sh", "-c"},
|
||||||
"metis", "remote-build",
|
"args": []string{
|
||||||
|
remoteWorkerEntrypoint(
|
||||||
|
true,
|
||||||
|
"remote-build",
|
||||||
"--inventory", a.settings.InventoryPath,
|
"--inventory", a.settings.InventoryPath,
|
||||||
"--node", node,
|
"--node", node,
|
||||||
"--cache", "/workspace/cache",
|
"--cache", "/workspace/cache",
|
||||||
@ -471,13 +481,10 @@ func (a *App) remoteBuildPodSpec(name, host, image, node, artifactRef, buildTag
|
|||||||
"--artifact-ref", artifactRef,
|
"--artifact-ref", artifactRef,
|
||||||
"--build-tag", buildTag,
|
"--build-tag", buildTag,
|
||||||
"--harbor-registry", a.settings.HarborRegistry,
|
"--harbor-registry", a.settings.HarborRegistry,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
"envFrom": []map[string]any{
|
"envFrom": []map[string]any{
|
||||||
{"configMapRef": map[string]any{"name": "metis"}},
|
{"configMapRef": map[string]any{"name": "metis"}},
|
||||||
{"secretRef": map[string]any{"name": "metis-harbor"}},
|
|
||||||
},
|
|
||||||
"env": []map[string]any{
|
|
||||||
{"name": "METIS_K3S_TOKEN", "valueFrom": map[string]any{"secretKeyRef": map[string]any{"name": "metis-runtime", "key": "k3s_token", "optional": true}}},
|
|
||||||
},
|
},
|
||||||
"volumeMounts": []map[string]any{
|
"volumeMounts": []map[string]any{
|
||||||
{"name": "workspace", "mountPath": "/workspace"},
|
{"name": "workspace", "mountPath": "/workspace"},
|
||||||
@ -500,6 +507,7 @@ func (a *App) remoteFlashPodSpec(name, host, image, node, device, artifactRef st
|
|||||||
"name": name,
|
"name": name,
|
||||||
"namespace": a.settings.Namespace,
|
"namespace": a.settings.Namespace,
|
||||||
"labels": map[string]string{"app": "metis-remote", "metis-run": "flash"},
|
"labels": map[string]string{"app": "metis-remote", "metis-run": "flash"},
|
||||||
|
"annotations": vaultRuntimeAnnotations(false),
|
||||||
},
|
},
|
||||||
"spec": map[string]any{
|
"spec": map[string]any{
|
||||||
"restartPolicy": "Never",
|
"restartPolicy": "Never",
|
||||||
@ -512,19 +520,22 @@ func (a *App) remoteFlashPodSpec(name, host, image, node, device, artifactRef st
|
|||||||
"name": "remote-flash",
|
"name": "remote-flash",
|
||||||
"image": image,
|
"image": image,
|
||||||
"imagePullPolicy": "Always",
|
"imagePullPolicy": "Always",
|
||||||
"command": []string{
|
"command": []string{"/bin/sh", "-c"},
|
||||||
"metis", "remote-flash",
|
"args": []string{
|
||||||
|
remoteWorkerEntrypoint(
|
||||||
|
false,
|
||||||
|
"remote-flash",
|
||||||
"--node", node,
|
"--node", node,
|
||||||
"--device", device,
|
"--device", device,
|
||||||
"--artifact-ref", artifactRef,
|
"--artifact-ref", artifactRef,
|
||||||
"--work-dir", "/workspace/flash",
|
"--work-dir", "/workspace/flash",
|
||||||
"--harbor-registry", a.settings.HarborRegistry,
|
"--harbor-registry", a.settings.HarborRegistry,
|
||||||
"--host-tmp-dir", mountedHostTmpDir(a.settings.HostTmpDir),
|
"--host-tmp-dir", mountedHostTmpDir(a.settings.HostTmpDir),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
"securityContext": map[string]any{"privileged": true, "runAsUser": 0},
|
"securityContext": map[string]any{"privileged": true, "runAsUser": 0},
|
||||||
"envFrom": []map[string]any{
|
"envFrom": []map[string]any{
|
||||||
{"configMapRef": map[string]any{"name": "metis"}},
|
{"configMapRef": map[string]any{"name": "metis"}},
|
||||||
{"secretRef": map[string]any{"name": "metis-harbor"}},
|
|
||||||
},
|
},
|
||||||
"volumeMounts": []map[string]any{
|
"volumeMounts": []map[string]any{
|
||||||
{"name": "workspace", "mountPath": "/workspace"},
|
{"name": "workspace", "mountPath": "/workspace"},
|
||||||
@ -572,3 +583,56 @@ func mountedHostTmpDir(path string) string {
|
|||||||
return filepath.Join("/host-tmp", strings.TrimPrefix(path, "/"))
|
return filepath.Join("/host-tmp", strings.TrimPrefix(path, "/"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func vaultRuntimeAnnotations(includeSSHKeys bool) map[string]string {
|
||||||
|
annotations := map[string]string{
|
||||||
|
"vault.hashicorp.com/agent-inject": "true",
|
||||||
|
"vault.hashicorp.com/agent-pre-populate-only": "true",
|
||||||
|
"vault.hashicorp.com/role": vaultRoleMaintenance,
|
||||||
|
"vault.hashicorp.com/agent-inject-secret-metis-runtime-env.sh": vaultRuntimeSecretPath,
|
||||||
|
"vault.hashicorp.com/agent-inject-template-metis-runtime-env.sh": `{{ with secret "kv/data/atlas/maintenance/metis-runtime" }}
|
||||||
|
export METIS_K3S_TOKEN="{{ .Data.data.k3s_token }}"
|
||||||
|
{{ end }}`,
|
||||||
|
"vault.hashicorp.com/agent-inject-secret-metis-harbor-env.sh": vaultHarborSecretPath,
|
||||||
|
"vault.hashicorp.com/agent-inject-template-metis-harbor-env.sh": `{{ with secret "kv/data/atlas/harbor/harbor-core" }}
|
||||||
|
export METIS_HARBOR_PASSWORD="{{ .Data.data.harbor_admin_password }}"
|
||||||
|
{{ end }}`,
|
||||||
|
}
|
||||||
|
if includeSSHKeys {
|
||||||
|
annotations["vault.hashicorp.com/agent-inject-secret-metis-ssh-env.sh"] = vaultSSHKeysSecretPath
|
||||||
|
annotations["vault.hashicorp.com/agent-inject-template-metis-ssh-env.sh"] = `{{ with secret "kv/data/atlas/maintenance/metis-ssh-keys" }}
|
||||||
|
export METIS_SSH_KEY_BASTION="{{ .Data.data.bastion_pub }}"
|
||||||
|
export METIS_SSH_KEY_BRAD="{{ .Data.data.brad_pub }}"
|
||||||
|
export METIS_SSH_KEY_HECATE_TETHYS="{{ .Data.data.hecate_tethys_pub }}"
|
||||||
|
{{ end }}`
|
||||||
|
}
|
||||||
|
return annotations
|
||||||
|
}
|
||||||
|
|
||||||
|
func remoteWorkerEntrypoint(includeSSHKeys bool, args ...string) string {
|
||||||
|
lines := []string{
|
||||||
|
"set -e",
|
||||||
|
". /vault/secrets/metis-runtime-env.sh",
|
||||||
|
". /vault/secrets/metis-harbor-env.sh",
|
||||||
|
}
|
||||||
|
if includeSSHKeys {
|
||||||
|
lines = append(lines, ". /vault/secrets/metis-ssh-env.sh")
|
||||||
|
}
|
||||||
|
lines = append(lines, "exec "+shellJoin(append([]string{"metis"}, args...)...))
|
||||||
|
return strings.Join(lines, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func shellJoin(args ...string) string {
|
||||||
|
quoted := make([]string, 0, len(args))
|
||||||
|
for _, arg := range args {
|
||||||
|
quoted = append(quoted, shellQuote(arg))
|
||||||
|
}
|
||||||
|
return strings.Join(quoted, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func shellQuote(value string) string {
|
||||||
|
if value == "" {
|
||||||
|
return "''"
|
||||||
|
}
|
||||||
|
return "'" + strings.ReplaceAll(value, "'", `'"'"'`) + "'"
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user