refactor: update SSH agent examples and module structure
- Refactor `gittools` to remove `sshagent` import - Update `sshagent.loaded()` to use `ssh-add -l` command - Relocate and expose `remote_copy` and `remote_auth` functions - Improve SSH agent examples and remove Linux tests - Optimize `sshagent` module and `play` function imports
This commit is contained in:
@@ -1,65 +0,0 @@
|
||||
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import freeflowuniverse.herolib.osal.sshagent
|
||||
import freeflowuniverse.herolib.builder
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
console.print_header('SSH Agent Management Example')
|
||||
|
||||
// Create SSH agent with single instance guarantee
|
||||
mut agent := sshagent.new_single()!
|
||||
println('SSH Agent initialized and ensured single instance')
|
||||
|
||||
// Show diagnostics
|
||||
diag := agent.diagnostics()
|
||||
console.print_header('SSH Agent Diagnostics:')
|
||||
for key, value in diag {
|
||||
console.print_item('${key}: ${value}')
|
||||
}
|
||||
|
||||
// Show current agent status
|
||||
println(agent)
|
||||
|
||||
// Example: Generate a test key if no keys exist
|
||||
if agent.keys.len == 0 {
|
||||
console.print_header('No keys found, generating example key...')
|
||||
mut key := agent.generate('example_key', '')!
|
||||
console.print_debug('Generated key: ${key}')
|
||||
|
||||
// Load the generated key
|
||||
key.load()!
|
||||
console.print_debug('Key loaded into agent')
|
||||
}
|
||||
|
||||
// Example: Push key to remote node (uncomment and modify for actual use)
|
||||
/*
|
||||
console.print_header('Testing remote node key deployment...')
|
||||
mut b := builder.new()!
|
||||
|
||||
// Create connection to remote node
|
||||
mut node := b.node_new(
|
||||
ipaddr: 'root@192.168.1.100:22' // Replace with actual remote host
|
||||
name: 'test_node'
|
||||
)!
|
||||
|
||||
if agent.keys.len > 0 {
|
||||
key_name := agent.keys[0].name
|
||||
console.print_debug('Pushing key "${key_name}" to remote node...')
|
||||
|
||||
// Push the key
|
||||
agent.push_key_to_node(mut node, key_name)!
|
||||
|
||||
// Verify access
|
||||
if agent.verify_key_access(mut node, key_name)! {
|
||||
console.print_debug('✓ SSH key access verified')
|
||||
} else {
|
||||
console.print_debug('✗ SSH key access verification failed')
|
||||
}
|
||||
|
||||
// Optional: Remove key from remote (for testing)
|
||||
// agent.remove_key_from_node(mut node, key_name)!
|
||||
// console.print_debug('Key removed from remote node')
|
||||
}
|
||||
*/
|
||||
|
||||
console.print_header('SSH Agent example completed successfully')
|
||||
@@ -1,51 +0,0 @@
|
||||
module main
|
||||
|
||||
import freeflowuniverse.herolib.osal.sshagent
|
||||
import freeflowuniverse.herolib.osal.linux
|
||||
|
||||
fn do1() ! {
|
||||
mut agent := sshagent.new()!
|
||||
println(agent)
|
||||
k := agent.get(name: 'kds') or { panic('notgound') }
|
||||
println(k)
|
||||
|
||||
mut k2 := agent.get(name: 'books') or { panic('notgound') }
|
||||
k2.load()!
|
||||
println(k2.agent)
|
||||
|
||||
println(agent)
|
||||
|
||||
k2.forget()!
|
||||
println(k2.agent)
|
||||
|
||||
// println(agent)
|
||||
}
|
||||
|
||||
fn test_user_mgmt() ! {
|
||||
mut lf := linux.new()!
|
||||
// Test user creation
|
||||
lf.user_create(
|
||||
name: 'testuser'
|
||||
sshkey: 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM3/2K7R8A/l0kM0/d'
|
||||
)!
|
||||
|
||||
// Test ssh key creation
|
||||
lf.sshkey_create(
|
||||
username: 'testuser'
|
||||
sshkey_name: 'testkey'
|
||||
)!
|
||||
|
||||
// Test ssh key deletion
|
||||
lf.sshkey_delete(
|
||||
username: 'testuser'
|
||||
sshkey_name: 'testkey'
|
||||
)!
|
||||
|
||||
// Test user deletion
|
||||
lf.user_delete(name: 'testuser')!
|
||||
}
|
||||
|
||||
fn main() {
|
||||
do1() or { panic(err) }
|
||||
test_user_mgmt() or { panic(err) }
|
||||
}
|
||||
55
examples/osal/sshagent/sshagent_example.vsh
Executable file
55
examples/osal/sshagent/sshagent_example.vsh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import freeflowuniverse.herolib.osal.sshagent
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
fn do_sshagent_example() ! {
|
||||
console.print_header('SSH Agent Basic Example')
|
||||
|
||||
mut agent := sshagent.new()!
|
||||
console.print_debug('SSH Agent created')
|
||||
println(agent)
|
||||
|
||||
// Generate a test key if no keys exist
|
||||
if agent.keys.len == 0 {
|
||||
console.print_debug('No keys found, generating test key...')
|
||||
mut test_key := agent.generate('test_example_key', '')!
|
||||
test_key.load()!
|
||||
console.print_debug('Test key generated and loaded')
|
||||
}
|
||||
|
||||
// Try to get a specific key (this will fail if key doesn't exist)
|
||||
console.print_debug('Looking for existing keys...')
|
||||
|
||||
if agent.keys.len > 0 {
|
||||
// Work with the first available key
|
||||
mut first_key := agent.keys[0]
|
||||
console.print_debug('Found key: ${first_key.name}')
|
||||
|
||||
if !first_key.loaded {
|
||||
console.print_debug('Loading key...')
|
||||
first_key.load()!
|
||||
console.print_debug('Key loaded')
|
||||
}
|
||||
|
||||
console.print_debug('Key details:')
|
||||
println(first_key)
|
||||
|
||||
// Show agent status after loading
|
||||
console.print_debug('Agent status after loading:')
|
||||
println(agent)
|
||||
|
||||
// Note: We don't call forget() in this example to avoid removing keys
|
||||
// first_key.forget()!
|
||||
} else {
|
||||
console.print_debug('No keys available in agent')
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
do_sshagent_example() or {
|
||||
console.print_debug('Error: ${err}')
|
||||
panic(err)
|
||||
}
|
||||
console.print_header('SSH Agent example completed successfully!')
|
||||
}
|
||||
85
examples/osal/sshagent/sshagent_example2.vsh
Executable file
85
examples/osal/sshagent/sshagent_example2.vsh
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import freeflowuniverse.herolib.osal.sshagent
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
console.print_header('SSH Agent Management Example')
|
||||
|
||||
// Create SSH agent with single instance guarantee
|
||||
mut agent := sshagent.new_single()!
|
||||
println('SSH Agent initialized and ensured single instance')
|
||||
|
||||
// Show diagnostics
|
||||
diag := agent.diagnostics()
|
||||
console.print_header('SSH Agent Diagnostics:')
|
||||
for key, value in diag {
|
||||
console.print_item('${key}: ${value}')
|
||||
}
|
||||
|
||||
// Show current agent status
|
||||
println(agent)
|
||||
|
||||
// Example: Generate a test key if no keys exist
|
||||
if agent.keys.len == 0 {
|
||||
console.print_header('No keys found, generating example key...')
|
||||
mut key := agent.generate('example_key', '')!
|
||||
console.print_debug('Generated key: ${key}')
|
||||
|
||||
// Load the generated key
|
||||
key.load()!
|
||||
console.print_debug('Key loaded into agent')
|
||||
}
|
||||
|
||||
// Example: Working with existing keys
|
||||
if agent.keys.len > 0 {
|
||||
console.print_header('Working with existing keys...')
|
||||
|
||||
for i, key in agent.keys {
|
||||
console.print_debug('Key ${i+1}: ${key.name}')
|
||||
console.print_debug(' Type: ${key.cat}')
|
||||
console.print_debug(' Loaded: ${key.loaded}')
|
||||
console.print_debug(' Email: ${key.email}')
|
||||
|
||||
if !key.loaded {
|
||||
console.print_debug(' Loading key...')
|
||||
mut key_mut := key
|
||||
key_mut.load() or {
|
||||
console.print_debug(' Failed to load: ${err}')
|
||||
continue
|
||||
}
|
||||
console.print_debug(' ✓ Key loaded successfully')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Example: Add a key from private key content
|
||||
console.print_header('Example: Adding a key from content...')
|
||||
console.print_debug('Note: This would normally use real private key content')
|
||||
console.print_debug('For security, we skip this in the example')
|
||||
|
||||
// Example: Generate and manage a new key
|
||||
console.print_header('Example: Generate a new test key...')
|
||||
test_key_name := 'test_key_example'
|
||||
|
||||
// Check if test key already exists
|
||||
existing_key := agent.get(name: test_key_name) or {
|
||||
console.print_debug('Test key does not exist, generating...')
|
||||
|
||||
// Generate new key
|
||||
mut new_key := agent.generate(test_key_name, '')!
|
||||
console.print_debug('✓ Generated new key: ${new_key.name}')
|
||||
|
||||
// Load it
|
||||
new_key.load()!
|
||||
console.print_debug('✓ Key loaded into agent')
|
||||
|
||||
new_key
|
||||
}
|
||||
|
||||
console.print_debug('Test key exists: ${existing_key.name}')
|
||||
|
||||
// Show final agent status
|
||||
console.print_header('Final SSH Agent Status:')
|
||||
println(agent)
|
||||
|
||||
console.print_header('SSH Agent example completed successfully')
|
||||
@@ -1,6 +1,5 @@
|
||||
module gittools
|
||||
|
||||
import freeflowuniverse.herolib.osal.sshagent
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.develop.vscode
|
||||
@@ -106,7 +105,9 @@ fn (self GitRepo) get_repo_url_for_clone() !string {
|
||||
// return url
|
||||
// }
|
||||
|
||||
if sshagent.loaded() {
|
||||
// Check if SSH agent is loaded (avoid importing sshagent to prevent circular dependency)
|
||||
ssh_check := os.execute('ssh-add -l')
|
||||
if ssh_check.exit_code == 0 {
|
||||
return self.get_ssh_url()!
|
||||
} else {
|
||||
return self.get_http_url()!
|
||||
|
||||
@@ -1,29 +1,31 @@
|
||||
module sshagent
|
||||
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
// Check if SSH agent is properly configured and all is good
|
||||
fn agent_check(mut agent SSHAgent) ! {
|
||||
console.print_header('SSH Agent Check')
|
||||
|
||||
|
||||
// Ensure single agent is running
|
||||
agent.ensure_single_agent()!
|
||||
|
||||
|
||||
// Get diagnostics
|
||||
diag := agent.diagnostics()
|
||||
|
||||
|
||||
for key, value in diag {
|
||||
console.print_item('${key}: ${value}')
|
||||
}
|
||||
|
||||
|
||||
// Verify agent is responsive
|
||||
if !agent.is_agent_responsive() {
|
||||
return error('SSH agent is not responsive')
|
||||
}
|
||||
|
||||
|
||||
// Load all existing keys from ~/.ssh that aren't loaded yet
|
||||
agent.init()!
|
||||
|
||||
|
||||
console.print_green('✓ SSH Agent is properly configured and running')
|
||||
|
||||
|
||||
// Show loaded keys
|
||||
loaded_keys := agent.keys_loaded()!
|
||||
console.print_item('Loaded keys: ${loaded_keys.len}')
|
||||
@@ -35,17 +37,17 @@ fn agent_check(mut agent SSHAgent) ! {
|
||||
// Create a new SSH key
|
||||
fn sshkey_create(mut agent SSHAgent, name string, passphrase string) ! {
|
||||
console.print_header('Creating SSH key: ${name}')
|
||||
|
||||
|
||||
// Check if key already exists
|
||||
if agent.exists(name: name) {
|
||||
console.print_debug('SSH key "${name}" already exists')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Generate new key
|
||||
mut key := agent.generate(name, passphrase)!
|
||||
console.print_green('✓ SSH key "${name}" created successfully')
|
||||
|
||||
|
||||
// Automatically load the key
|
||||
key.load()!
|
||||
console.print_green('✓ SSH key "${name}" loaded into agent')
|
||||
@@ -54,28 +56,28 @@ fn sshkey_create(mut agent SSHAgent, name string, passphrase string) ! {
|
||||
// Delete an SSH key
|
||||
fn sshkey_delete(mut agent SSHAgent, name string) ! {
|
||||
console.print_header('Deleting SSH key: ${name}')
|
||||
|
||||
|
||||
// Check if key exists
|
||||
mut key := agent.get(name: name) or {
|
||||
console.print_debug('SSH key "${name}" does not exist')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Get key paths before deletion
|
||||
key_path := key.keypath() or {
|
||||
mut key_path := key.keypath() or {
|
||||
console.print_debug('Private key path not available for "${name}"')
|
||||
key.keypath_pub() or { return } // Just to trigger the path lookup
|
||||
}
|
||||
key_pub_path := key.keypath_pub() or {
|
||||
mut key_pub_path := key.keypath_pub() or {
|
||||
console.print_debug('Public key path not available for "${name}"')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Remove from agent if loaded (temporarily disabled due to reset_ssh panic)
|
||||
// if key.loaded {
|
||||
// key.forget()!
|
||||
// }
|
||||
|
||||
|
||||
// Delete key files
|
||||
if key_path.exists() {
|
||||
key_path.delete()!
|
||||
@@ -85,26 +87,24 @@ fn sshkey_delete(mut agent SSHAgent, name string) ! {
|
||||
key_pub_path.delete()!
|
||||
console.print_debug('Deleted public key: ${key_pub_path.path}')
|
||||
}
|
||||
|
||||
|
||||
// Reinitialize agent to update key list
|
||||
agent.init()!
|
||||
|
||||
|
||||
console.print_green('✓ SSH key "${name}" deleted successfully')
|
||||
}
|
||||
|
||||
// Load SSH key into agent
|
||||
fn sshkey_load(mut agent SSHAgent, name string) ! {
|
||||
console.print_header('Loading SSH key: ${name}')
|
||||
|
||||
mut key := agent.get(name: name) or {
|
||||
return error('SSH key "${name}" not found')
|
||||
}
|
||||
|
||||
|
||||
mut key := agent.get(name: name) or { return error('SSH key "${name}" not found') }
|
||||
|
||||
if key.loaded {
|
||||
console.print_debug('SSH key "${name}" is already loaded')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
key.load()!
|
||||
console.print_green('✓ SSH key "${name}" loaded into agent')
|
||||
}
|
||||
@@ -112,28 +112,24 @@ fn sshkey_load(mut agent SSHAgent, name string) ! {
|
||||
// Check if SSH key is valid
|
||||
fn sshkey_check(mut agent SSHAgent, name string) ! {
|
||||
console.print_header('Checking SSH key: ${name}')
|
||||
|
||||
mut key := agent.get(name: name) or {
|
||||
return error('SSH key "${name}" not found')
|
||||
}
|
||||
|
||||
|
||||
mut key := agent.get(name: name) or { return error('SSH key "${name}" not found') }
|
||||
|
||||
// Check if key files exist
|
||||
key_path := key.keypath() or {
|
||||
return error('Private key file not found for "${name}"')
|
||||
}
|
||||
|
||||
key_pub_path := key.keypath_pub() or {
|
||||
mut key_path := key.keypath() or { return error('Private key file not found for "${name}"') }
|
||||
|
||||
mut key_pub_path := key.keypath_pub() or {
|
||||
return error('Public key file not found for "${name}"')
|
||||
}
|
||||
|
||||
|
||||
if !key_path.exists() {
|
||||
return error('Private key file does not exist: ${key_path.path}')
|
||||
}
|
||||
|
||||
|
||||
if !key_pub_path.exists() {
|
||||
return error('Public key file does not exist: ${key_pub_path.path}')
|
||||
}
|
||||
|
||||
|
||||
// Verify key can be loaded (if not already loaded)
|
||||
if !key.loaded {
|
||||
// Test load without actually loading (since forget is disabled)
|
||||
@@ -142,70 +138,15 @@ fn sshkey_check(mut agent SSHAgent, name string) ! {
|
||||
return error('Invalid private key format in "${name}"')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
console.print_item('Key type: ${key.cat}')
|
||||
console.print_item('Loaded: ${key.loaded}')
|
||||
console.print_item('Email: ${key.email}')
|
||||
console.print_item('Private key: ${key_path.path}')
|
||||
console.print_item('Public key: ${key_pub_path.path}')
|
||||
|
||||
|
||||
console.print_green('✓ SSH key "${name}" is valid')
|
||||
}
|
||||
|
||||
// Copy private key to remote node
|
||||
fn remote_copy(mut agent SSHAgent, node_addr string, key_name string) ! {
|
||||
console.print_header('Copying SSH key "${key_name}" to ${node_addr}')
|
||||
|
||||
// Get the key
|
||||
mut key := agent.get(name: key_name) or {
|
||||
return error('SSH key "${key_name}" not found')
|
||||
}
|
||||
|
||||
// Create builder node
|
||||
mut b := builder.new()!
|
||||
mut node := b.node_new(ipaddr: node_addr)!
|
||||
|
||||
// Get private key content
|
||||
key_path := key.keypath()!
|
||||
if !key_path.exists() {
|
||||
return error('Private key file not found: ${key_path.path}')
|
||||
}
|
||||
|
||||
private_key_content := key_path.read()!
|
||||
|
||||
// Get home directory on remote
|
||||
home_dir := node.environ_get()!['HOME'] or {
|
||||
return error('Could not determine HOME directory on remote node')
|
||||
}
|
||||
|
||||
remote_ssh_dir := '${home_dir}/.ssh'
|
||||
remote_key_path := '${remote_ssh_dir}/${key_name}'
|
||||
|
||||
// Ensure .ssh directory exists with correct permissions
|
||||
node.exec_silent('mkdir -p ${remote_ssh_dir}')!
|
||||
node.exec_silent('chmod 700 ${remote_ssh_dir}')!
|
||||
|
||||
// Copy private key to remote
|
||||
node.file_write(remote_key_path, private_key_content)!
|
||||
node.exec_silent('chmod 600 ${remote_key_path}')!
|
||||
|
||||
// Generate public key on remote
|
||||
node.exec_silent('ssh-keygen -y -f ${remote_key_path} > ${remote_key_path}.pub')!
|
||||
node.exec_silent('chmod 644 ${remote_key_path}.pub')!
|
||||
|
||||
console.print_green('✓ SSH key "${key_name}" copied to ${node_addr}')
|
||||
}
|
||||
|
||||
// Add public key to authorized_keys on remote node
|
||||
fn remote_auth(mut agent SSHAgent, node_addr string, key_name string) ! {
|
||||
console.print_header('Adding SSH key "${key_name}" to authorized_keys on ${node_addr}')
|
||||
|
||||
// Create builder node
|
||||
mut b := builder.new()!
|
||||
mut node := b.node_new(ipaddr: node_addr)!
|
||||
|
||||
// Use existing builder integration
|
||||
agent.push_key_to_node(mut node, key_name)!
|
||||
|
||||
console.print_green('✓ SSH key "${key_name}" added to authorized_keys on ${node_addr}')
|
||||
}
|
||||
// Note: remote_copy and remote_auth functions moved to builder_integration.v
|
||||
// to avoid circular dependencies
|
||||
|
||||
@@ -10,27 +10,27 @@ pub fn (mut agent SSHAgent) push_key_to_node(mut node builder.Node, key_name str
|
||||
if node_info['category'] != 'ssh' {
|
||||
return error('Can only push keys to SSH nodes, got: ${node_info['category']}')
|
||||
}
|
||||
|
||||
|
||||
// Find the key
|
||||
mut key := agent.get(name: key_name) or {
|
||||
return error('SSH key "${key_name}" not found in agent')
|
||||
}
|
||||
|
||||
|
||||
// Get public key content
|
||||
pubkey_content := key.keypub()!
|
||||
|
||||
|
||||
// Check if authorized_keys file exists on remote
|
||||
home_dir := node.environ_get()!['HOME'] or {
|
||||
return error('Could not determine HOME directory on remote node')
|
||||
}
|
||||
|
||||
|
||||
ssh_dir := '${home_dir}/.ssh'
|
||||
authorized_keys_path := '${ssh_dir}/authorized_keys'
|
||||
|
||||
|
||||
// Ensure .ssh directory exists with correct permissions
|
||||
node.exec_silent('mkdir -p ${ssh_dir}')!
|
||||
node.exec_silent('chmod 700 ${ssh_dir}')!
|
||||
|
||||
|
||||
// Check if key already exists
|
||||
if node.file_exists(authorized_keys_path) {
|
||||
existing_keys := node.file_read(authorized_keys_path)!
|
||||
@@ -39,11 +39,11 @@ pub fn (mut agent SSHAgent) push_key_to_node(mut node builder.Node, key_name str
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add key to authorized_keys
|
||||
node.exec_silent('echo "${pubkey_content}" >> ${authorized_keys_path}')!
|
||||
node.exec_silent('chmod 600 ${authorized_keys_path}')!
|
||||
|
||||
|
||||
console.print_debug('SSH key "${key_name}" successfully pushed to node')
|
||||
}
|
||||
|
||||
@@ -54,31 +54,31 @@ pub fn (mut agent SSHAgent) remove_key_from_node(mut node builder.Node, key_name
|
||||
if node_info['category'] != 'ssh' {
|
||||
return error('Can only remove keys from SSH nodes, got: ${node_info['category']}')
|
||||
}
|
||||
|
||||
|
||||
// Find the key
|
||||
mut key := agent.get(name: key_name) or {
|
||||
return error('SSH key "${key_name}" not found in agent')
|
||||
}
|
||||
|
||||
|
||||
// Get public key content
|
||||
pubkey_content := key.keypub()!
|
||||
|
||||
|
||||
// Get authorized_keys path
|
||||
home_dir := node.environ_get()!['HOME'] or {
|
||||
return error('Could not determine HOME directory on remote node')
|
||||
}
|
||||
|
||||
|
||||
authorized_keys_path := '${home_dir}/.ssh/authorized_keys'
|
||||
|
||||
|
||||
if !node.file_exists(authorized_keys_path) {
|
||||
console.print_debug('authorized_keys file does not exist on remote node')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Remove the key line from authorized_keys
|
||||
escaped_key := pubkey_content.replace('/', '\\/')
|
||||
node.exec_silent('sed -i "\\|${escaped_key}|d" ${authorized_keys_path}')!
|
||||
|
||||
|
||||
console.print_debug('SSH key "${key_name}" removed from remote node')
|
||||
}
|
||||
|
||||
@@ -90,11 +90,65 @@ pub fn (mut agent SSHAgent) verify_key_access(mut node builder.Node, key_name st
|
||||
if node_info['category'] != 'ssh' {
|
||||
return error('Can only verify access to SSH nodes')
|
||||
}
|
||||
|
||||
|
||||
// Test basic connectivity
|
||||
result := node.exec_silent('echo "SSH key verification successful"') or {
|
||||
return false
|
||||
}
|
||||
|
||||
result := node.exec_silent('echo "SSH key verification successful"') or { return false }
|
||||
|
||||
return result.contains('SSH key verification successful')
|
||||
}
|
||||
}
|
||||
|
||||
// Copy private key to remote node
|
||||
pub fn remote_copy(mut agent SSHAgent, node_addr string, key_name string) ! {
|
||||
console.print_header('Copying SSH key "${key_name}" to ${node_addr}')
|
||||
|
||||
// Get the key
|
||||
mut key := agent.get(name: key_name) or { return error('SSH key "${key_name}" not found') }
|
||||
|
||||
// Create builder node
|
||||
mut b := builder.new()!
|
||||
mut node := b.node_new(ipaddr: node_addr)!
|
||||
|
||||
// Get private key content
|
||||
mut key_path := key.keypath()!
|
||||
if !key_path.exists() {
|
||||
return error('Private key file not found: ${key_path.path}')
|
||||
}
|
||||
|
||||
private_key_content := key_path.read()!
|
||||
|
||||
// Get home directory on remote
|
||||
home_dir := node.environ_get()!['HOME'] or {
|
||||
return error('Could not determine HOME directory on remote node')
|
||||
}
|
||||
|
||||
remote_ssh_dir := '${home_dir}/.ssh'
|
||||
remote_key_path := '${remote_ssh_dir}/${key_name}'
|
||||
|
||||
// Ensure .ssh directory exists with correct permissions
|
||||
node.exec_silent('mkdir -p ${remote_ssh_dir}')!
|
||||
node.exec_silent('chmod 700 ${remote_ssh_dir}')!
|
||||
|
||||
// Copy private key to remote
|
||||
node.file_write(remote_key_path, private_key_content)!
|
||||
node.exec_silent('chmod 600 ${remote_key_path}')!
|
||||
|
||||
// Generate public key on remote
|
||||
node.exec_silent('ssh-keygen -y -f ${remote_key_path} > ${remote_key_path}.pub')!
|
||||
node.exec_silent('chmod 644 ${remote_key_path}.pub')!
|
||||
|
||||
console.print_green('✓ SSH key "${key_name}" copied to ${node_addr}')
|
||||
}
|
||||
|
||||
// Add public key to authorized_keys on remote node
|
||||
pub fn remote_auth(mut agent SSHAgent, node_addr string, key_name string) ! {
|
||||
console.print_header('Adding SSH key "${key_name}" to authorized_keys on ${node_addr}')
|
||||
|
||||
// Create builder node
|
||||
mut b := builder.new()!
|
||||
mut node := b.node_new(ipaddr: node_addr)!
|
||||
|
||||
// Use existing builder integration
|
||||
agent.push_key_to_node(mut node, key_name)!
|
||||
|
||||
console.print_green('✓ SSH key "${key_name}" added to authorized_keys on ${node_addr}')
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ pub fn new(args_ SSHAgentNewArgs) !SSHAgent {
|
||||
}
|
||||
|
||||
pub fn loaded() bool {
|
||||
mut agent := new() or { panic(err) }
|
||||
return agent.active
|
||||
res := os.execute('ssh-add -l')
|
||||
return res.exit_code == 0
|
||||
}
|
||||
|
||||
// create new SSH agent with single instance guarantee
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module sshagent
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook { PlayBook }
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.builder
|
||||
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
if !plbook.exists(filter: 'sshagent.') {
|
||||
@@ -25,7 +23,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
mut p := action.params
|
||||
name := p.get('name')!
|
||||
passphrase := p.get_default('passphrase', '')!
|
||||
|
||||
|
||||
sshkey_create(mut agent, name, passphrase)!
|
||||
action.done = true
|
||||
}
|
||||
@@ -35,7 +33,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
for mut action in delete_actions {
|
||||
mut p := action.params
|
||||
name := p.get('name')!
|
||||
|
||||
|
||||
sshkey_delete(mut agent, name)!
|
||||
action.done = true
|
||||
}
|
||||
@@ -45,7 +43,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
for mut action in load_actions {
|
||||
mut p := action.params
|
||||
name := p.get('name')!
|
||||
|
||||
|
||||
sshkey_load(mut agent, name)!
|
||||
action.done = true
|
||||
}
|
||||
@@ -55,7 +53,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
for mut action in check_key_actions {
|
||||
mut p := action.params
|
||||
name := p.get('name')!
|
||||
|
||||
|
||||
sshkey_check(mut agent, name)!
|
||||
action.done = true
|
||||
}
|
||||
@@ -66,7 +64,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
mut p := action.params
|
||||
node_addr := p.get('node')!
|
||||
key_name := p.get('name')!
|
||||
|
||||
|
||||
remote_copy(mut agent, node_addr, key_name)!
|
||||
action.done = true
|
||||
}
|
||||
@@ -77,7 +75,7 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
mut p := action.params
|
||||
node_addr := p.get('node')!
|
||||
key_name := p.get('name')!
|
||||
|
||||
|
||||
remote_auth(mut agent, node_addr, key_name)!
|
||||
action.done = true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user