Skip to content

Commit

Permalink
impl horaectl
Browse files Browse the repository at this point in the history
  • Loading branch information
baojinri committed Feb 27, 2024
1 parent 62ffffc commit e1b7466
Show file tree
Hide file tree
Showing 13 changed files with 1,018 additions and 59 deletions.
420 changes: 361 additions & 59 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ license = "Apache-2.0"
resolver = "2"
# In alphabetical order
members = [
"horaectl",
"integration_tests",
"integration_tests/sdk/rust",
"src/analytic_engine",
Expand Down
42 changes: 42 additions & 0 deletions horaectl/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# 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.

[package]
name = "horaectl"

[package.license]
workspace = true

[package.version]
workspace = true

[package.authors]
workspace = true

[package.edition]
workspace = true

[dependencies]
chrono = "0.4.33"
clap = { version = "4.4.18", features = ["derive"] }
once_cell = "1.19.0"
package = "0.0.0"
prettytable = "0.10.0"
reqwest = {version = "0.11.24", features = ["json"]}
serde = { version = "1.0.196", features = ["derive"] }
shell-words = "1.1.0"
tokio = { version = "1.0.0", features = ["rt", "rt-multi-thread", "macros"] }
45 changes: 45 additions & 0 deletions horaectl/src/cmd/cluster.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// 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 clap::{ArgMatches, Command};

use crate::{
cmd::{
cluster_diagnose::diagnose,
cluster_list::list,
cluster_schedule::{schedule, schedule_resolve},
},
operation::cluster::{clusters_diagnose, clusters_list},
};

pub fn cluster() -> Command {
Command::new("cluster")
.about("Operations on cluster")
.alias("c")
.subcommand(list())
.subcommand(diagnose())
.subcommand(schedule())
}

pub async fn cluster_resolve(arg_matches: &ArgMatches) {
match arg_matches.subcommand() {
Some(("list", _)) => clusters_list().await,
Some(("diagnose", _)) => clusters_diagnose().await,
Some(("schedule", sub_matches)) => schedule_resolve(sub_matches).await,
_ => {}
}
}
24 changes: 24 additions & 0 deletions horaectl/src/cmd/cluster_diagnose.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// 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 clap::Command;

pub fn diagnose() -> Command {
Command::new("diagnose")
.about("Cluster diagnose")
.alias("d")
}
22 changes: 22 additions & 0 deletions horaectl/src/cmd/cluster_list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// 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 clap::Command;

pub fn list() -> Command {
Command::new("list").about("Cluster list").alias("l")
}
48 changes: 48 additions & 0 deletions horaectl/src/cmd/cluster_schedule.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// 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 clap::{Arg, ArgMatches, Command};

use crate::operation::cluster::{clusters_schedule_get, clusters_schedule_set};

pub fn schedule() -> Command {
Command::new("schedule")
.about("Cluster schedule")
.alias("s")
.subcommand(Command::new("get").about("Get the schedule status"))
.subcommand(
Command::new("set").about("Set the schedule status").arg(
Arg::new("enable")
.help("Enable or disable schedule")
.long("enable")
.short('e')
.default_value("false")
.value_parser(clap::value_parser!(bool)),
),
)
}

pub async fn schedule_resolve(arg_matches: &ArgMatches) {
match arg_matches.subcommand() {
Some(("get", _)) => clusters_schedule_get().await,
Some(("set", sub_matches)) => {
let enable = sub_matches.get_one::<bool>("enable").copied().unwrap();
clusters_schedule_set(enable).await;
}
_ => {}
}
}
120 changes: 120 additions & 0 deletions horaectl/src/cmd/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// 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.

mod cluster;
mod cluster_diagnose;
mod cluster_list;
mod cluster_schedule;
pub mod quit;

use std::{io, io::Write};

use clap::{Arg, Command};

use crate::{
cmd::{
cluster::{cluster, cluster_resolve},
quit::quit,
},
util::{CLUSTER_NAME, META_ADDR},
};

fn cmd() -> Command {
let horaectl = Command::new("horaectl")
.about("horaectl is a command line tool for HoraeDB")
.arg(
Arg::new("meta_addr")
.short('m')
.long("meta")
.value_name("META_ADDR")
.default_value("127.0.0.1:8080")
.help("meta addr is used to connect to meta server"),
)
.arg(
Arg::new("cluster_name")
.short('c')
.long("cluster")
.value_name("CLUSTER_NAME")
.default_value("defaultCluster")
.help("Cluster to connect to"),
);

let matches = horaectl.clone().get_matches();
META_ADDR
.set(matches.get_one::<String>("meta_addr").unwrap().to_string())
.unwrap();
CLUSTER_NAME
.set(
matches
.get_one::<String>("cluster_name")
.unwrap()
.to_string(),
)
.unwrap();

horaectl.subcommand(cluster()).subcommand(quit())
}

pub async fn execute() {
let horaectl = cmd();
loop {
print_prompt(META_ADDR.get().unwrap(), CLUSTER_NAME.get().unwrap());

let args = match read_args() {
Ok(args) => args,
Err(e) => {
println!("{}", e);
continue;
}
};

match horaectl.clone().try_get_matches_from(args) {
Ok(arg_matches) => match arg_matches.subcommand() {
Some(("quit", _)) => {
println!("bye");
break;
}
Some(("cluster", sub_matches)) => cluster_resolve(sub_matches).await,
_ => {}
},
Err(e) => {
println!("{}", e)
}
}
}
}

fn read_args() -> Result<Vec<String>, String> {
io::stdout().flush().unwrap();
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.map_err(|e| e.to_string())?;

let input = input.trim();
if input.is_empty() {
return Err("No arguments provided".into());
}

let mut args = vec!["horaectl".to_string()];
args.extend(shell_words::split(input).map_err(|e| e.to_string())?);
Ok(args)
}

fn print_prompt(address: &str, cluster: &str) {
print!("{}({}) > ", address, cluster);
}
25 changes: 25 additions & 0 deletions horaectl/src/cmd/quit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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 clap::Command;

pub fn quit() -> Command {
Command::new("quit")
.about("Quit horaectl")
.alias("q")
.alias("exit")
}
27 changes: 27 additions & 0 deletions horaectl/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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.

mod cmd;
mod operation;
mod util;

use crate::cmd::execute;

#[tokio::main]
async fn main() {
execute().await;
}
Loading

0 comments on commit e1b7466

Please sign in to comment.