Skip to content

Commit

Permalink
[spr] initial version
Browse files Browse the repository at this point in the history
Created using spr 1.3.6-beta.1
  • Loading branch information
sunshowers committed Aug 2, 2024
1 parent 4643454 commit 9706689
Show file tree
Hide file tree
Showing 34 changed files with 1,656 additions and 1,297 deletions.
89 changes: 81 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ members = [
"cockroach-admin/api",
"cockroach-admin/types",
"common",
"dev-tools/cert-dev",
"dev-tools/ch-dev",
"dev-tools/crdb-seed",
"dev-tools/db-dev",
"dev-tools/downloader",
"dev-tools/mgs-dev",
"dev-tools/omdb",
"dev-tools/omicron-dev",
"dev-tools/omicron-dev-lib",
"dev-tools/openapi-manager",
"dev-tools/oxlog",
"dev-tools/reconfigurator-cli",
Expand Down Expand Up @@ -122,10 +127,15 @@ default-members = [
"cockroach-admin/api",
"cockroach-admin/types",
"common",
"dev-tools/cert-dev",
"dev-tools/ch-dev",
"dev-tools/crdb-seed",
"dev-tools/db-dev",
"dev-tools/downloader",
"dev-tools/mgs-dev",
"dev-tools/omdb",
"dev-tools/omicron-dev",
"dev-tools/omicron-dev-lib",
"dev-tools/openapi-manager",
"dev-tools/oxlog",
"dev-tools/reconfigurator-cli",
Expand Down Expand Up @@ -405,6 +415,7 @@ num = { version = "0.4.3", default-features = false, features = [ "libm" ] }
omicron-certificates = { path = "certificates" }
omicron-cockroach-admin = { path = "cockroach-admin" }
omicron-common = { path = "common" }
omicron-dev-lib = { path = "dev-tools/omicron-dev-lib" }
omicron-gateway = { path = "gateway" }
omicron-nexus = { path = "nexus" }
omicron-omdb = { path = "dev-tools/omdb" }
Expand Down
2 changes: 1 addition & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ The server also accepts command-line flags for overriding the values of the conf
parameters.

The packages downloaded by `cargo xtask download clickhouse` include a `config.xml` file with them.
You should probably run ClickHouse via the `omicron-dev` tool, but if you decide to run it
You should probably run ClickHouse via the `ch-dev` tool, but if you decide to run it
manually, you can start the server with:

[source,text]
Expand Down
23 changes: 23 additions & 0 deletions dev-tools/cert-dev/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "cert-dev"
version = "0.1.0"
edition = "2021"
license = "MPL-2.0"

[lints]
workspace = true

[dependencies]
anyhow.workspace = true
camino.workspace = true
clap.workspace = true
libc.workspace = true
omicron-workspace-hack.workspace = true
tokio.workspace = true
rcgen.workspace = true

[dev-dependencies]
camino-tempfile.workspace = true
omicron-test-utils.workspace = true
openssl.workspace = true
subprocess.workspace = true
91 changes: 91 additions & 0 deletions dev-tools/cert-dev/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use std::{io::Write, os::unix::fs::OpenOptionsExt};

use anyhow::Context;
use camino::{Utf8Path, Utf8PathBuf};
use clap::{Parser, Subcommand};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let args = CertDevApp::parse();
args.exec().await
}

/// Utilities for working with certificates.
#[derive(Parser)]
struct CertDevApp {
#[clap(subcommand)]
command: CertDevCmd,
}

impl CertDevApp {
async fn exec(self) -> anyhow::Result<()> {
match self.command {
CertDevCmd::Create(args) => args.exec().await,
}
}
}

#[derive(Subcommand)]
enum CertDevCmd {
/// Create a self-signed certificate for use with Omicron
Create(CertCreateArgs),
}

#[derive(Clone, Debug, Parser)]
pub struct CertCreateArgs {
/// path to where the generated certificate and key files should go
/// (e.g., "out/initial-" would cause the files to be called
/// "out/initial-cert.pem" and "out/initial-key.pem")
#[clap(action)]
output_base: Utf8PathBuf,

/// DNS names that the certificate claims to be valid for (subject
/// alternative names)
#[clap(action, required = true)]
server_names: Vec<String>,
}

impl CertCreateArgs {
pub async fn exec(&self) -> Result<(), anyhow::Error> {
let cert =
rcgen::generate_simple_self_signed(self.server_names.clone())
.context("generating certificate")?;
let cert_pem =
cert.serialize_pem().context("serializing certificate as PEM")?;
let key_pem = cert.serialize_private_key_pem();

let cert_path =
Utf8PathBuf::from(format!("{}cert.pem", self.output_base));
write_private_file(&cert_path, cert_pem.as_bytes())
.context("writing certificate file")?;
println!("wrote certificate to {}", cert_path);

let key_path =
Utf8PathBuf::from(format!("{}key.pem", self.output_base));
write_private_file(&key_path, key_pem.as_bytes())
.context("writing private key file")?;
println!("wrote private key to {}", key_path);

Ok(())
}
}

#[cfg_attr(not(target_os = "macos"), allow(clippy::useless_conversion))]
fn write_private_file(
path: &Utf8Path,
contents: &[u8],
) -> Result<(), anyhow::Error> {
// The file should be readable and writable by the user only.
let perms = libc::S_IRUSR | libc::S_IWUSR;
let mut file = std::fs::OpenOptions::new()
.write(true)
.create_new(true)
.mode(perms.into()) // into() needed on mac only
.open(path)
.with_context(|| format!("open {:?} for writing", path))?;
file.write_all(contents).with_context(|| format!("write to {:?}", path))
}
54 changes: 54 additions & 0 deletions dev-tools/cert-dev/tests/test-cert-dev.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Tests for cert-dev.
use std::path::PathBuf;

use anyhow::Context;
use omicron_test_utils::dev::test_cmds::{
assert_exit_code, path_to_executable, run_command, EXIT_SUCCESS,
};
use subprocess::Exec;

const CMD_CERT_DEV: &str = env!("CARGO_BIN_EXE_cert-dev");

fn path_to_cert_dev() -> PathBuf {
path_to_executable(CMD_CERT_DEV)
}

#[test]
fn test_cert_create() {
let tmpdir = camino_tempfile::tempdir().unwrap();
println!("tmpdir: {}", tmpdir.path());
let output_base = format!("{}/test-", tmpdir.path());
let exec = Exec::cmd(path_to_cert_dev())
.arg("create")
.arg(output_base)
.arg("foo.example")
.arg("bar.example");
let (exit_status, _, stderr_text) = run_command(exec);
assert_exit_code(exit_status, EXIT_SUCCESS, &stderr_text);
let cert_path = tmpdir.path().join("test-cert.pem");
let key_path = tmpdir.path().join("test-key.pem");
let cert_contents = std::fs::read(&cert_path)
.with_context(|| format!("reading certificate path {:?}", cert_path))
.unwrap();
let key_contents = std::fs::read(&key_path)
.with_context(|| format!("reading private key path: {:?}", key_path))
.unwrap();
let certs_pem = openssl::x509::X509::stack_from_pem(&cert_contents)
.context("parsing certificate")
.unwrap();
let private_key = openssl::pkey::PKey::private_key_from_pem(&key_contents)
.context("parsing private key")
.unwrap();
assert!(certs_pem
.iter()
.last()
.unwrap()
.public_key()
.unwrap()
.public_eq(&private_key));
}
24 changes: 24 additions & 0 deletions dev-tools/ch-dev/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "ch-dev"
version = "0.1.0"
edition = "2021"
license = "MPL-2.0"

[lints]
workspace = true

[build-dependencies]
omicron-rpaths.workspace = true

[dependencies]
anyhow.workspace = true
clap.workspace = true
dropshot.workspace = true
futures.workspace = true
libc.workspace = true
omicron-test-utils.workspace = true
omicron-workspace-hack.workspace = true
# See omicron-rpaths for more about the "pq-sys" dependency.
pq-sys = "*"
signal-hook-tokio.workspace = true
tokio.workspace = true
Loading

0 comments on commit 9706689

Please sign in to comment.