use std::fs; //, io}; use std::fs::OpenOptions; use std::io::Write; use std::path::Path; use rfm::mkdir; use std::collections::HashMap; use serde_yaml::Value; use serde_dhall; // use std::process::{Command}; use std::collections::BTreeMap; use anyhow::{anyhow,Result,Context,Error}; use tkdr::tera_lib::make_template_content; use clds::pkgs::{get_pkgs_vers,PkgInfo,PkgVers}; use clds::clouds::defs::{ CfgRs, CloudEnv, Cloud, ConfigResources, Server, TskSrvc, MainResourcesConfig, }; use clds::clouds::on_clouds::env_cloud; use clds::tsksrvcs::run_tsksrvcs_on_providers; use crate::defs::{load_key}; use crate::errors::AppError; use crate::utils; // use tempfile::tempfile; // use std::fs::File; //use base64_stream::FromBase64Writer; /// On_cloud /// Load env and config files /// Load `tsksrvc` (can be group of tsksrvcs) /// On each `element` in `config` run `tsksrvc` pub async fn on_cloud(tsksrvc: &str, cmd: &str, nxt: &str, source: &str, listhosts: &str, force: u8) -> Result { let mut cloud = Cloud::default(); cloud.env = CloudEnv::new(force, load_key().await); cloud.providers = Cloud::load_providers().await; env_cloud(source, &mut cloud.env).await?; get_pkgs_vers(&mut cloud).await?; cloud.env.listhosts = String::from(listhosts); let cfg_path = format!("{}/{}/{}/{}",&cloud.env.home,&source,&cloud.env.config_root,&cloud.env.config_path); let mut cfg_data = fs::read_to_string(&cfg_path).with_context(|| format!("Failed to read 'cfg_path' from {}", &cfg_path))?; let mut cfg: MainResourcesConfig = serde_yaml::from_str(&cfg_data)?; let provider = cloud.providers.get(&cfg.provider).with_context(|| format!("Provider '{}'' not defined", &cfg.provider))?; // Load tsksrvcs.yaml into TskSrvcs // for (i, tsk) in tsksrvcs.tsksrvcsList.iter().enumerate() { // if tsksrvc == "all" || tsk.name.as_str() == tsksrvc { // match tsk.target.as_str() { // "servers" => on_cloud_server(&mut cloud, i, tsk).await?, // _ => println!("Target '{}' undefined from {}", &tsk.target, cloud.env.config_path), // } // } // } //let tsksrvcs_path = format!("{}/home/{}/tsksrvcs.yaml",&cloud.env.path,&source); //let mut tsksrvcs_data = fs::read_to_string(&tsksrvcs_path).with_context(|| format!("Failed to read 'tsksrvcs_path' from {}", &tsksrvcs_path))?; //let mut tsksrvcs: TskSrvcs = serde_yaml::from_str(&tsksrvcs_data)?; // .with_context(|| format!("Failed to parse 'tsksrvcs_path' from {}", &tsksrvcs_path))?; run_tsksrvcs_on_providers(provider, &cfg_data, &cloud, tsksrvc, &cmd, &nxt, &cfg).await?; // .map_err(|e| AppError::ErrorInternalServerError(format!("Template error {}",e)))?; //utils::tera_render(tera: &mut Tera, tpl_context: tera::Context, tpl: &str, output_path: &str, append: bool).await?; // dbg!(&cloud); // for (i, elem) in config_res.servers.iter().enumerate() { // dbg!(&elem); // } // // println!("DONE: {} - {}",&tsksrvc,&source); // if &envmnt::get_or("WEB_MODE", "") == "" { // // println!("{}",&str_config_res); // println!("DONE: {} ",&cfg_path); // } Ok("done".to_string()) } /* pub fn get_packages_serde_value(src: &Option>>, key: &str, target: &str, dflt: String) -> String { let mut target_value= String::from(""); if let Some(pkgs) = &src { if let Some(val) = pkgs.get(key) { if let Some(item) = val.get(target) { dbg!(item); match item.as_str() { Some(v) => target_value=v.to_string(), None => target_value=dflt.to_owned(), } // target_value = tkdr::tera_lib::get_yaml_val(item,dflt); }; } } target_value } pub async fn create_full_config(cloud: &mut Cloud) -> Result<()> { let mut output_path = format!("{}/specs",&cloud.env.provision); if ! Path::new(&output_path).exists() { fs::create_dir(&output_path)?; println!("{} created", &output_path); } output_path = format!("{}/specs/config.yaml",&cloud.env.provision); if Path::new(&output_path).exists() && cloud.env.force < 1u8 { println!("Found created {}", &output_path); return Ok(()); } let mut config_resources = cloud.config_resources.to_owned(); config_resources.servers = Vec::new(); let mut file =std::fs::File::create(&output_path).with_context(|| format!("Failed to open to file: {}",&output_path))?; let mut str_config_resources = serde_yaml::to_string(&config_resources).with_context(|| format!("Failed creating yaml from config_resources in {}",&cloud.env.provision))?; str_config_resources = str_config_resources.replace("servers: []","servers: \n"); file.write(&str_config_resources.as_bytes())?; // fs.write apped to fs::write!(&output_path); /* for (i, elem) in cloud.config_resources.servers.iter().enumerate() { if let Some(tpl) = &elem.tpl { let tpl_path = get_env_path("",&tpl, &cloud.env.source , &cloud.env.tpls_path,true).await?; let tpl_content= fs::read_to_string(&tpl_path).with_context(|| format!("Failed to read 'tpl_path' from {}", &tpl_path))?; // println!("Template {} -> {}",&tpl, &tpl_path); utils::tpl_data_server(&elem, &tpl_content, &output_path, true).await.with_context(|| format!("Failed 'ConfigResources' template {}",&tpl_path))?; if let Some(specs) = &elem.spec { if let Some(pkgs_tpl) = &specs.tplPkgs { let pkgs_tpl_path = get_env_path("",&pkgs_tpl, &cloud.env.source , &cloud.env.tpls_path, true).await?; let pkgs_tpl_content= fs::read_to_string(&pkgs_tpl_path).with_context(|| format!("Failed to read 'pkgs_tpl_path' from {}", &pkgs_tpl_path))?; utils::tpl_data_map(&cloud.env.pkgs_vers, &pkgs_tpl_content, &output_path, true).await.with_context(|| format!("Failed render 'versions' on template {}",&pkgs_tpl_path))?; // let mut file = OpenOptions::new().append(true).open(&output_path)?; // file.write(&pkgs_tpl_content.as_bytes())?; } } } } */ println!("Full 'config_resources' created"); Ok(()) } /// On_cloud_servers run tsksrvcs pub async fn on_cloud_server(cloud: &mut Cloud, pos: usize, tsksrvc: &TskSrvc) -> Result<()> { let mut tsksrvc_path = String::from(""); if tsksrvc.path.len() > 0 { tsksrvc_path = get_env_path(format!("CLOUDS_TSKSRVC_{}",&tsksrvc.name).as_str(), &tsksrvc.path, "" , &cloud.env.root_tsksrvcs,true).await?; } match tsksrvc.name.as_str() { "createserver" | "modifyip" | "startserver" => { for (i, elem) in cloud.config_resources.servers.iter().enumerate() { println!("TskSrvc {}th {} in {}th {}: {} ", pos+1, &tsksrvc.name,i+1, &tsksrvc.target, &elem.hostname); println!("{}",&tsksrvc_path); if let Some(provider) = &cloud.config_resources.provider { match provider.as_str() { "upcloud" => if let Some(provider_def) = cloud.providers.get(provider) { let cmd = format!("{} {} {}",&provider_def.runner,&provider_def.args, &tsksrvc.name); println!("Provider '{}' to create '{} -f {}/config_resources.yaml",provider,&cmd, &cloud.env.provision); }, "manual" => { println!("Provider '{}' create manually",&provider); if tsksrvc.path.len() > 0 { tkdr::utils::run_command(&tsksrvc.path,"","")?; } }, _ => println!("Provider '{}' to create '{}' undefined",&provider,&elem.hostname), } } } }, _ => println!("TskSrvc '{}' undefined on {}", &tsksrvc.name, &tsksrvc.target), } Ok(()) } */