177 lines
7.5 KiB
Rust
177 lines
7.5 KiB
Rust
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<String> {
|
|
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<HashMap<String,HashMap<String,serde_yaml::Value>>>, 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(())
|
|
}
|
|
*/ |