Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion crates/appcred-sql/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ impl ApplicationCredentialBackend for SqlBackend {
state: &ServiceState,
rec: ApplicationCredentialCreate,
) -> Result<ApplicationCredentialCreateResponse, ApplicationCredentialProviderError> {
Ok(application_credential::create(&state.config, &state.db, rec).await?)
let config = state.config_manager.config.read().await;
Ok(application_credential::create(&config, &state.db, rec).await?)
}

/// Get a single application credential by ID.
Expand Down
4 changes: 2 additions & 2 deletions crates/assignment-sql/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ mod tests {
use std::collections::{BTreeMap, BTreeSet};
use std::sync::Arc;

use openstack_keystone_config::Config;
use openstack_keystone_config::{Config, ConfigManager};
use openstack_keystone_core::keystone::Service;
use openstack_keystone_core::policy::MockPolicy;
use openstack_keystone_core::provider::Provider;
Expand All @@ -285,7 +285,7 @@ mod tests {
async fn get_mock_state(db: DatabaseConnection, provider: Provider) -> Arc<Service> {
Arc::new(
Service::new(
Config::default(),
ConfigManager::not_watched(Config::default()),
db,
provider,
Arc::new(MockPolicy::default()),
Expand Down
1 change: 1 addition & 0 deletions crates/cli-manage/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ comfy-table = "7.2"
openstack-keystone = { version = "0.1", path = "../keystone" }
openstack-keystone-config = { version = "0.1", path = "../config" }
openstack-keystone-distributed-storage = { version = "0.1", path = "../storage/"}
secrecy.workspace = true
tokio = { workspace = true, features = ["fs", "macros"] }
tonic = { workspace = true, features = ["tls-aws-lc" ] }

Expand Down
77 changes: 59 additions & 18 deletions crates/cli-manage/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@

use async_trait::async_trait;
use clap::{Parser, Subcommand};
use color_eyre::{Report, eyre::WrapErr};
use color_eyre::{Report, eyre::OptionExt};
use secrecy::ExposeSecret;
use tonic::transport::{Certificate, Channel, ClientTlsConfig, Identity, Uri};

use openstack_keystone_config::{Config, DistributedStorageConfiguration};
use openstack_keystone_config::Config;
use openstack_keystone_distributed_storage::protobuf::raft::cluster_admin_service_client::ClusterAdminServiceClient;

mod demote;
Expand Down Expand Up @@ -70,29 +71,69 @@ enum StorageCommands {
RemovePeer(RemovePeerCommand),
}

pub async fn get_grpc_client_tls_config(
cfg: &DistributedStorageConfiguration,
) -> Result<ClientTlsConfig, Report> {
/// Prepare the [ClientTlsConfig].
///
/// # Parameters
/// - `config`: The Keystone [`Config`] instance.
///
/// # Returns
/// A `Result` containing the `ClientTlsConfig`.
pub async fn get_grpc_client_tls_config(config: &Config) -> Result<ClientTlsConfig, Report> {
let identity = Identity::from_pem(
std::fs::read_to_string(&cfg.tls_configuration.tls_cert_file)
.wrap_err("reading client cert file")?,
std::fs::read_to_string(&cfg.tls_configuration.tls_key_file)
.wrap_err("reading client cert key file")?,
config
.distributed_storage
.as_ref()
.and_then(|x| x.tls_configuration.tls_cert_content.as_ref())
.or(config
.listener
.tls_configuration
.as_ref()
.and_then(|x| x.tls_cert_content.as_ref()))
.ok_or_eyre("TLS cert file missing")?
.expose_secret(),
config
.distributed_storage
.as_ref()
.and_then(|x| x.tls_configuration.tls_key_content.as_ref())
.or(config
.listener
.tls_configuration
.as_ref()
.and_then(|x| x.tls_key_content.as_ref()))
.ok_or_eyre("TLS key file missing")?
.expose_secret(),
);
let mut config = ClientTlsConfig::new().identity(identity);
if let Some(ca) = &cfg.tls_configuration.tls_client_ca_file {
// ca for validation of the "server"
config = config.ca_certificate(Certificate::from_pem(std::fs::read_to_string(&ca)?));
}
return Ok(config);
let mut tls_client_config = ClientTlsConfig::new().identity(identity);
if let Some(cert_ca) = config
.distributed_storage
.as_ref()
.and_then(|x| x.tls_configuration.tls_client_ca_content.as_ref())
.or(config
.listener
.tls_configuration
.as_ref()
.and_then(|x| x.tls_client_ca_content.as_ref()))
{
tls_client_config =
tls_client_config.ca_certificate(Certificate::from_pem(cert_ca.expose_secret()));
};
Ok(tls_client_config)
}

async fn get_grpc_client(
cfg: &DistributedStorageConfiguration,
cfg: &Config,
addr: Option<Uri>,
) -> Result<ClusterAdminServiceClient<Channel>, Report> {
let ep = Channel::builder(addr.unwrap_or(cfg.cluster_addr.clone()))
.tls_config(get_grpc_client_tls_config(cfg).await?)?;
let ep = Channel::builder(
addr.unwrap_or(
cfg.distributed_storage
.as_ref()
.ok_or_eyre("distributed storage configuration missing")?
.cluster_addr
.clone(),
),
)
.tls_config(get_grpc_client_tls_config(cfg).await?)?;
let client = ClusterAdminServiceClient::new(ep.connect().await?);
Ok(client)
}
4 changes: 2 additions & 2 deletions crates/cli-manage/src/storage/demote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ pub(super) struct DemoteCommand {
#[async_trait]
impl PerformAction for DemoteCommand {
async fn take_action(self, config: &Config) -> Result<(), Report> {
if let Some(cfg) = &config.distributed_storage {
let mut client = get_grpc_client(cfg, None).await?;
if config.distributed_storage.is_some() {
let mut client = get_grpc_client(config, None).await?;

let membership = client
.metrics(())
Expand Down
2 changes: 1 addition & 1 deletion crates/cli-manage/src/storage/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl PerformAction for InitCommand {
async fn take_action(self, config: &Config) -> Result<(), Report> {
if let Some(cfg) = &config.distributed_storage {
if let (Some(host), Some(port)) = (cfg.cluster_addr.host(), cfg.cluster_addr.port()) {
let mut client = get_grpc_client(cfg, None).await?;
let mut client = get_grpc_client(config, None).await?;

client
.init(pb::raft::InitRequest {
Expand Down
2 changes: 1 addition & 1 deletion crates/cli-manage/src/storage/join.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl PerformAction for JoinCommand {
async fn take_action(self, config: &Config) -> Result<(), Report> {
if let Some(cfg) = &config.distributed_storage {
if let (Some(host), Some(port)) = (cfg.cluster_addr.host(), cfg.cluster_addr.port()) {
let mut client = get_grpc_client(cfg, Some(self.cluster_addr)).await?;
let mut client = get_grpc_client(config, Some(self.cluster_addr)).await?;

client
.add_learner(pb::raft::AddLearnerRequest {
Expand Down
4 changes: 2 additions & 2 deletions crates/cli-manage/src/storage/list_peers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ pub(super) struct ListPeersCommand {}
impl PerformAction for ListPeersCommand {
#[allow(clippy::print_stdout)]
async fn take_action(self, config: &Config) -> Result<(), Report> {
if let Some(cfg) = &config.distributed_storage {
let mut client = get_grpc_client(cfg, None).await?;
if config.distributed_storage.is_some() {
let mut client = get_grpc_client(config, None).await?;

let metrics = client.metrics(()).await?.into_inner();
let membership = metrics.membership.unwrap_or_default();
Expand Down
4 changes: 2 additions & 2 deletions crates/cli-manage/src/storage/promote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ pub(super) struct PromoteCommand {
#[async_trait]
impl PerformAction for PromoteCommand {
async fn take_action(self, config: &Config) -> Result<(), Report> {
if let Some(cfg) = &config.distributed_storage {
let mut client = get_grpc_client(cfg, None).await?;
if config.distributed_storage.is_some() {
let mut client = get_grpc_client(config, None).await?;

let membership = client
.metrics(())
Expand Down
4 changes: 2 additions & 2 deletions crates/cli-manage/src/storage/remove_peer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ pub(super) struct RemovePeerCommand {
#[async_trait]
impl PerformAction for RemovePeerCommand {
async fn take_action(self, config: &Config) -> Result<(), Report> {
if let Some(cfg) = &config.distributed_storage {
let mut client = get_grpc_client(cfg, None).await?;
if config.distributed_storage.is_some() {
let mut client = get_grpc_client(config, None).await?;

let membership = client
.metrics(())
Expand Down
5 changes: 5 additions & 0 deletions crates/config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,24 @@ exclude.workspace = true
[dependencies]
chrono = { workspace = true, features = ["now"] }
config = { workspace = true, features = ["async", "ini"] }
derive_builder.workspace = true
eyre.workspace = true
http.workspace = true
http-serde = "2.1.1"
notify = "8.2.0"
regex.workspace = true
secrecy = { workspace = true, features = ["serde"] }
serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = ["fs", "rt", "sync", "time"] }
tracing.workspace = true
url = { workspace = true, features = ["serde"] }
url-macro.workspace = true

[dev-dependencies]
serde_json.workspace = true
temp-env = "0.3.6"
tempfile.workspace = true
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }

[lints]
workspace = true
Loading
Loading