use crate::cli::parser::CliParser;
use crate::connection::ssh::SshFactory;
use crate::connection::local::LocalFactory;
use crate::connection::no::NoFactory;
use crate::playbooks::traversal::{playbook_traversal,RunState};
use crate::playbooks::context::PlaybookContext;
use crate::playbooks::visitor::PlaybookVisitor;
use crate::inventory::inventory::Inventory;
use std::sync::{Arc,RwLock};
struct CheckVisitor {}
impl CheckVisitor {
pub fn new() -> Self { Self {} }
}
impl PlaybookVisitor for CheckVisitor {
fn is_check_mode(&self) -> bool { return true; }
}
struct LiveVisitor {}
impl LiveVisitor {
pub fn new() -> Self { Self {} }
}
impl PlaybookVisitor for LiveVisitor {
fn is_check_mode(&self) -> bool { return false; }
}
enum CheckMode {
Yes,
No
}
enum ConnectionMode {
Ssh,
Local,
Simulate
}
pub fn playbook_ssh(inventory: &Arc<RwLock<Inventory>>, parser: &CliParser) -> i32 {
return playbook(inventory, parser, CheckMode::No, ConnectionMode::Ssh);
}
pub fn playbook_check_ssh(inventory: &Arc<RwLock<Inventory>>, parser: &CliParser) -> i32 {
return playbook(inventory, parser, CheckMode::Yes, ConnectionMode::Ssh);
}
pub fn playbook_local(inventory: &Arc<RwLock<Inventory>>, parser: &CliParser) -> i32 {
return playbook(inventory, parser, CheckMode::No, ConnectionMode::Local);
}
pub fn playbook_check_local(inventory: &Arc<RwLock<Inventory>>, parser: &CliParser) -> i32 {
return playbook(inventory, parser, CheckMode::Yes, ConnectionMode::Local);
}
pub fn playbook_simulate(inventory: &Arc<RwLock<Inventory>>, parser: &CliParser) -> i32 {
return playbook(inventory, parser, CheckMode::No, ConnectionMode::Simulate);
}
fn playbook(inventory: &Arc<RwLock<Inventory>>, parser: &CliParser, check_mode: CheckMode, connection_mode: ConnectionMode) -> i32 {
let run_state = Arc::new(RunState {
inventory: Arc::clone(inventory),
playbook_paths: Arc::clone(&parser.playbook_paths),
role_paths: Arc::clone(&parser.role_paths),
limit_hosts: parser.limit_hosts.clone(),
limit_groups: parser.limit_groups.clone(),
batch_size: parser.batch_size.clone(),
context: Arc::new(RwLock::new(PlaybookContext::new(parser))),
visitor: match check_mode {
CheckMode::Yes => Arc::new(RwLock::new(CheckVisitor::new())),
CheckMode::No => Arc::new(RwLock::new(LiveVisitor::new())),
},
connection_factory: match connection_mode {
ConnectionMode::Ssh => Arc::new(RwLock::new(SshFactory::new(inventory, parser.forward_agent, parser.login_password.clone()))),
ConnectionMode::Local => Arc::new(RwLock::new(LocalFactory::new(inventory))),
ConnectionMode::Simulate => Arc::new(RwLock::new(NoFactory::new()))
},
tags: parser.tags.clone(),
allow_localhost_delegation: parser.allow_localhost_delegation
});
return match playbook_traversal(&run_state) {
Ok(_) => run_state.visitor.read().unwrap().get_exit_status(&run_state.context),
Err(s) => { println!("{}", s); 1 }
};
}