blob: f69e973a0066eb8eeda52a9348d666b9245460bb [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
use askama::Template;
use serde::{Deserialize, Serialize};
use std::fs;
use std::fs::File;
use std::io::Write;
use std::path;
use std::path::Path;
use std::path::PathBuf;
use structopt::StructOpt;
#[derive(Serialize, Deserialize)]
struct BuildConfigToml {
as_root_ca_cert: ConfigSource,
auditor_public_keys: Vec<ConfigSource>,
grpc_config: GrpcConfig,
attestation_validity_secs: u64,
inbound: Inbound,
}
#[derive(Serialize, Deserialize)]
struct Inbound {
access_control: Vec<String>,
authentication: Vec<String>,
management: Vec<String>,
storage: Vec<String>,
scheduler: Vec<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all(serialize = "snake_case", deserialize = "snake_case"))]
struct GrpcConfig {
max_encoding_message_size: usize,
max_decoding_message_size: usize,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all(serialize = "snake_case", deserialize = "snake_case"))]
enum ConfigSource {
Path(PathBuf),
}
fn display_config_source(config: &ConfigSource) -> String {
match config {
ConfigSource::Path(p) => match p.extension().and_then(std::ffi::OsStr::to_str) {
Some("pem") => {
let content = &fs::read(p).unwrap_or_else(|e| {
panic!("Failed to read file: {}, error: {:?}", p.display(), e)
});
let pem = pem::parse(content).expect("Cannot parse PEM file");
format!("{:?}", pem.contents)
}
_ => {
let content = &fs::read(p).unwrap_or_else(|e| {
panic!("Failed to read file: {}, error: {:?}", p.display(), e)
});
format!("{:?}", content)
}
},
}
}
#[derive(Template)]
#[template(path = "config.j2")]
struct ConfigTemplate {
as_root_ca_cert: String,
auditor_public_keys: Vec<String>,
grpc_config: GrpcConfig,
attestation_validity_secs: u64,
inbound: Inbound,
}
fn generate_build_config(toml: &Path, out: &Path) {
let contents = fs::read_to_string(toml).expect("Something went wrong reading the file");
let config: BuildConfigToml = toml::from_str(&contents).expect("Failed to parse the config.");
let as_root_ca_cert = display_config_source(&config.as_root_ca_cert);
let mut auditor_public_keys: Vec<String> = vec![];
for key in &config.auditor_public_keys {
let auditor_pulic_key = display_config_source(key);
auditor_public_keys.push(auditor_pulic_key);
}
let config_template = ConfigTemplate {
as_root_ca_cert,
auditor_public_keys,
grpc_config: config.grpc_config,
attestation_validity_secs: config.attestation_validity_secs,
inbound: config.inbound,
};
let mut f = File::create(out)
.unwrap_or_else(|e| panic!("Failed to create file: {}, error: {:?}", out.display(), e));
f.write_all(config_template.render().unwrap().as_bytes())
.unwrap_or_else(|e| panic!("Failed to write file: {}, error: {:?}", out.display(), e));
}
#[derive(Debug, StructOpt)]
struct Cli {
#[structopt(short = "t", required = true)]
/// Path to the config file in toml.
toml_path: path::PathBuf,
#[structopt(short = "o", required = true)]
/// Configures the output path where generated Rust file will be written.
out_path: path::PathBuf,
}
fn main() {
let args = Cli::from_args();
generate_build_config(&args.toml_path, &args.out_path);
}