Skip to content

Commit d4cc911

Browse files
committed
Add support for key data and password
1 parent a11291c commit d4cc911

File tree

5 files changed

+382
-12
lines changed

5 files changed

+382
-12
lines changed

api/v1alpha1/exporterhost_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ type SSHCredentials struct {
4949
User string `json:"user,omitempty"`
5050
// KeyFile is the path to the SSH private key file.
5151
KeyFile string `json:"keyFile,omitempty"`
52+
// SSHKeyData is the SSH private key data as a string.
53+
SSHKeyData string `json:"sshKeyData,omitempty"`
54+
// SSHKeyPassword is the password for encrypted SSH private keys.
55+
SSHKeyPassword string `json:"sshKeyPassword,omitempty"`
5256
// Password is the SSH password (if not using key-based auth).
5357
Password string `json:"password,omitempty"`
5458
// Port is the SSH port (default is 22).

config/crd/bases/meta.jumpstarter.dev_exporterhosts.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ spec:
8282
port:
8383
description: Port is the SSH port (default is 22).
8484
type: integer
85+
sshKeyData:
86+
description: SSHKeyData is the SSH private key data as a string.
87+
type: string
88+
sshKeyPassword:
89+
description: SSHKeyPassword is the password for encrypted
90+
SSH private keys.
91+
type: string
8592
user:
8693
description: User is the SSH username.
8794
type: string

example/devices/on-lab/ti-jacinto-j784s4xevm-01/ti-jacinto-j784s4xevm-01-sidekick.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ spec:
1717
ssh:
1818
host: "$( name ).auto.bos2.dc.example.com"
1919
user: "admin"
20-
keyFile: "~/.ssh/id_rsa"
20+
sshKey: "$( vars.exporter-ssh-key )"
2121
power:
2222
snmp:
2323
host: "some-pdu-hostname.auto.eng.bos2.bc.somedomain.com"

internal/exporter/ssh/ssh.go

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,34 @@ func (m *SSHHostManager) createSshClient() (*ssh.Client, error) {
8888
if err != nil {
8989
return nil, fmt.Errorf("failed to read SSH key file: %w", err)
9090
}
91-
signer, err := ssh.ParsePrivateKey(key)
92-
if err != nil {
93-
return nil, fmt.Errorf("failed to parse SSH private key: %w", err)
91+
var signer ssh.Signer
92+
if m.ExporterHost.Spec.Management.SSH.SSHKeyPassword != "" {
93+
signer, err = ssh.ParsePrivateKeyWithPassphrase(key, []byte(m.ExporterHost.Spec.Management.SSH.SSHKeyPassword))
94+
if err != nil {
95+
return nil, fmt.Errorf("failed to parse encrypted SSH private key from file: %w", err)
96+
}
97+
} else {
98+
signer, err = ssh.ParsePrivateKey(key)
99+
if err != nil {
100+
return nil, fmt.Errorf("failed to parse SSH private key from file: %w", err)
101+
}
102+
}
103+
auth = append(auth, ssh.PublicKeys(signer))
104+
}
105+
106+
if m.ExporterHost.Spec.Management.SSH.SSHKeyData != "" {
107+
var signer ssh.Signer
108+
var err error
109+
if m.ExporterHost.Spec.Management.SSH.SSHKeyPassword != "" {
110+
signer, err = ssh.ParsePrivateKeyWithPassphrase([]byte(m.ExporterHost.Spec.Management.SSH.SSHKeyData), []byte(m.ExporterHost.Spec.Management.SSH.SSHKeyPassword))
111+
if err != nil {
112+
return nil, fmt.Errorf("failed to parse encrypted SSH private key from sshKeyData: %w", err)
113+
}
114+
} else {
115+
signer, err = ssh.ParsePrivateKey([]byte(m.ExporterHost.Spec.Management.SSH.SSHKeyData))
116+
if err != nil {
117+
return nil, fmt.Errorf("failed to parse SSH private key from sshKeyData: %w", err)
118+
}
94119
}
95120
auth = append(auth, ssh.PublicKeys(signer))
96121
}
@@ -102,19 +127,18 @@ func (m *SSHHostManager) createSshClient() (*ssh.Client, error) {
102127
// Check if SSH agent is running and use it if available
103128
agentSocket := os.Getenv("SSH_AUTH_SOCK")
104129
if agentSocket != "" {
105-
log.Fatal("SSH_AUTH_SOCK environment variable not set. Is ssh-agent running?")
106-
107130
// Connect to the agent's socket.
108131
conn, err := net.Dial("unix", agentSocket)
109132
if err != nil {
110-
log.Fatalf("Failed to open SSH_AUTH_SOCK: %v", err)
111-
}
112-
defer conn.Close() // nolint:errcheck
133+
log.Printf("Failed to connect to SSH agent: %v", err)
134+
} else {
135+
defer conn.Close() // nolint:errcheck
113136

114-
// Create a new agent client.
115-
agentClient := agent.NewClient(conn)
137+
// Create a new agent client.
138+
agentClient := agent.NewClient(conn)
116139

117-
auth = append(auth, ssh.PublicKeysCallback(agentClient.Signers))
140+
auth = append(auth, ssh.PublicKeysCallback(agentClient.Signers))
141+
}
118142
}
119143

120144
config := &ssh.ClientConfig{

0 commit comments

Comments
 (0)