diff --git a/rs/cli/src/commands/mod.rs b/rs/cli/src/commands/mod.rs index 2eb3a6288..a858b9891 100644 --- a/rs/cli/src/commands/mod.rs +++ b/rs/cli/src/commands/mod.rs @@ -1,3 +1,5 @@ +use std::path::PathBuf; + use crate::commands::subnet::Subnet; use api_boundary_nodes::ApiBoundaryNodes; use clap::Args as ClapArgs; @@ -141,6 +143,9 @@ pub struct DiscourseOpts { /// prompt user for the link #[clap(long, env = "DISCOURSE_SKIP_POST_CREATION", global = true)] pub(crate) discourse_skip_post_creation: bool, + + #[clap(long, env = "DISCOURSE_SUBNET_TOPIC_OVERRIDE_FILE_PATH", global = true)] + pub(crate) discourse_subnet_topic_override_file_path: Option, } #[derive(Parser, Debug)] diff --git a/rs/cli/src/ctx.rs b/rs/cli/src/ctx.rs index c1cbca63a..2ec474196 100644 --- a/rs/cli/src/ctx.rs +++ b/rs/cli/src/ctx.rs @@ -281,6 +281,7 @@ impl DreContext { // It can happen because the tool runs in offline mode, or if its a dry run. self.store.is_offline() || self.dry_run, self.discourse_opts.discourse_skip_post_creation, + self.discourse_opts.discourse_subnet_topic_override_file_path.clone(), )?); *self.discourse_client.borrow_mut() = Some(client.clone()); Ok(client) diff --git a/rs/cli/src/discourse_client.rs b/rs/cli/src/discourse_client.rs index faaa6b919..256354e5c 100644 --- a/rs/cli/src/discourse_client.rs +++ b/rs/cli/src/discourse_client.rs @@ -1,4 +1,9 @@ -use std::{collections::BTreeMap, fmt::Display, time::Duration}; +use std::{ + collections::BTreeMap, + fmt::Display, + path::{Path, PathBuf}, + time::Duration, +}; use futures::{future::BoxFuture, TryFutureExt}; use ic_types::PrincipalId; @@ -26,10 +31,18 @@ pub struct DiscourseClientImp { api_user: String, offline: bool, skip_forum_post_creation: bool, + subnet_topic_file_override: Option, } impl DiscourseClientImp { - pub fn new(url: String, api_key: String, api_user: String, offline: bool, skip_forum_post_creation: bool) -> anyhow::Result { + pub fn new( + url: String, + api_key: String, + api_user: String, + offline: bool, + skip_forum_post_creation: bool, + subnet_topic_file_override: Option, + ) -> anyhow::Result { let client = reqwest::Client::builder().timeout(Duration::from_secs(30)).build()?; Ok(Self { @@ -39,6 +52,7 @@ impl DiscourseClientImp { api_user, offline, skip_forum_post_creation, + subnet_topic_file_override, }) } @@ -209,6 +223,11 @@ fn get_subnet_topics_map() -> BTreeMap { serde_json::from_str(SUBNET_TOPICS_AND_SLUGS).unwrap() } +fn get_subnet_topics_from_path(path: &Path) -> anyhow::Result> { + let file = std::fs::File::open(path)?; + serde_json::from_reader(file).map_err(anyhow::Error::from) +} + impl DiscourseClient for DiscourseClientImp { fn create_replace_nodes_forum_post(&self, subnet_id: PrincipalId, body: String) -> BoxFuture<'_, anyhow::Result>> { Box::pin(async move { @@ -216,7 +235,10 @@ impl DiscourseClient for DiscourseClientImp { return Ok(None); } - let subnet_topic_map = get_subnet_topics_map(); + let subnet_topic_map = match &self.subnet_topic_file_override { + Some(path) => get_subnet_topics_from_path(path)?, + None => get_subnet_topics_map(), + }; let topic_info = subnet_topic_map.get(&subnet_id).ok_or(anyhow::anyhow!( "Subnet {} not found in the subnet topic map. Don't know where to create a forum post", subnet_id.to_string()