mirror of
https://github.com/moghtech/komodo.git
synced 2026-04-29 12:43:26 -05:00
Big Terminal refactor + most commands run directly / bypass 'sh -c "..."'
This commit is contained in:
@@ -20,6 +20,7 @@ mod server;
|
||||
mod stack;
|
||||
mod sync;
|
||||
mod tag;
|
||||
mod terminal;
|
||||
mod toml;
|
||||
mod update;
|
||||
mod user;
|
||||
@@ -43,6 +44,7 @@ pub use server::*;
|
||||
pub use stack::*;
|
||||
pub use sync::*;
|
||||
pub use tag::*;
|
||||
pub use terminal::*;
|
||||
pub use toml::*;
|
||||
pub use update::*;
|
||||
pub use user::*;
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::entities::{
|
||||
I64, Timelength,
|
||||
server::{
|
||||
PeripheryInformation, Server, ServerActionState, ServerListItem,
|
||||
ServerQuery, ServerState, TerminalInfo, TerminalInfoWithServer,
|
||||
ServerQuery, ServerState,
|
||||
},
|
||||
stats::{
|
||||
SystemInformation, SystemProcess, SystemStats, SystemStatsRecord,
|
||||
@@ -265,51 +265,3 @@ pub struct GetServersSummaryResponse {
|
||||
/// The number of disabled servers.
|
||||
pub disabled: I64,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
/// List the current terminals on specified server.
|
||||
/// Response: [ListTerminalsResponse].
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, Default, Resolve, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(KomodoReadRequest)]
|
||||
#[response(ListTerminalsResponse)]
|
||||
#[error(serror::Error)]
|
||||
pub struct ListTerminals {
|
||||
/// Id or name
|
||||
#[serde(alias = "id", alias = "name")]
|
||||
pub server: String,
|
||||
/// Force a fresh call to Periphery for the list.
|
||||
/// Otherwise the response will be cached for 30s
|
||||
#[serde(default)]
|
||||
pub fresh: bool,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
pub type ListTerminalsResponse = Vec<TerminalInfo>;
|
||||
|
||||
//
|
||||
|
||||
/// List the current terminals on specified server.
|
||||
/// Response: [ListAllTerminalsResponse].
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, Default, Resolve, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(KomodoReadRequest)]
|
||||
#[response(ListAllTerminalsResponse)]
|
||||
#[error(serror::Error)]
|
||||
pub struct ListAllTerminals {
|
||||
/// optional structured query to filter servers.
|
||||
#[serde(default)]
|
||||
pub query: ServerQuery,
|
||||
/// Force a fresh call to Periphery for the list.
|
||||
/// Otherwise the response will be cached for 30s
|
||||
#[serde(default)]
|
||||
pub fresh: bool,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
pub type ListAllTerminalsResponse = Vec<TerminalInfoWithServer>;
|
||||
|
||||
30
client/core/rs/src/api/read/terminal.rs
Normal file
30
client/core/rs/src/api/read/terminal.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use derive_empty_traits::EmptyTraits;
|
||||
use resolver_api::Resolve;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
use crate::entities::terminal::{Terminal, TerminalTarget};
|
||||
|
||||
use super::KomodoReadRequest;
|
||||
|
||||
//
|
||||
|
||||
/// List Terminals.
|
||||
/// Response: [ListTerminalsResponse].
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Debug, Clone, Default, Serialize, Deserialize, Resolve, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(KomodoReadRequest)]
|
||||
#[response(ListTerminalsResponse)]
|
||||
#[error(serror::Error)]
|
||||
pub struct ListTerminals {
|
||||
/// Filter the Terminals returned by the Target.
|
||||
pub target: Option<TerminalTarget>,
|
||||
/// Return results with resource names instead of ids.
|
||||
#[serde(default)]
|
||||
pub use_names: bool,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
pub type ListTerminalsResponse = Vec<Terminal>;
|
||||
@@ -1,181 +1,61 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
use crate::api::write::TerminalRecreateMode;
|
||||
use crate::entities::terminal::{
|
||||
ContainerTerminalMode, TerminalRecreateMode, TerminalTarget,
|
||||
};
|
||||
|
||||
/// Query to connect to a terminal (interactive shell over websocket) on the given server.
|
||||
/// Connect to a Terminal.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ConnectTerminalQuery {
|
||||
/// Server Id or name
|
||||
pub server: String,
|
||||
/// Each periphery can keep multiple terminals open.
|
||||
/// If a terminals with the specified name does not exist,
|
||||
/// the call will fail.
|
||||
/// Create a terminal using [CreateTerminal][super::write::server::CreateTerminal]
|
||||
pub terminal: String,
|
||||
/// The target to create terminal for.
|
||||
pub target: TerminalTarget,
|
||||
/// Terminal name to connect to.
|
||||
/// If it may not exist yet, also pass 'init' params
|
||||
/// to include initialization.
|
||||
/// Default: Depends on target.
|
||||
pub terminal: Option<String>,
|
||||
/// Pass to init the terminal session
|
||||
/// for when the terminal doesn't already exist.
|
||||
///
|
||||
/// Example: ?...(query)&init[command]=bash&init[recreate]=DifferentCommand
|
||||
pub init: Option<InitTerminal>,
|
||||
}
|
||||
|
||||
/// Args to init the Terminal if needed.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct InitTerminal {
|
||||
/// The shell command (eg `bash`) to init the shell.
|
||||
///
|
||||
/// Default:
|
||||
/// - Server: Configured on each Periphery
|
||||
/// - Container: `sh`
|
||||
pub command: Option<String>,
|
||||
/// Default: `Never`
|
||||
#[serde(default)]
|
||||
pub recreate: TerminalRecreateMode,
|
||||
/// Only relevant for container-type terminals.
|
||||
/// Specify the container terminal mode (`exec` or `attach`).
|
||||
/// Default: `exec`
|
||||
pub mode: Option<ContainerTerminalMode>,
|
||||
}
|
||||
|
||||
/// Execute a terminal command on the given server.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ExecuteTerminalBody {
|
||||
/// Server Id or name
|
||||
pub server: String,
|
||||
/// The name of the terminal on the server to use to execute.
|
||||
pub terminal: String,
|
||||
/// The target to create terminal for.
|
||||
pub target: TerminalTarget,
|
||||
/// Terminal name to connect to.
|
||||
/// If it may not exist yet, also pass 'init' params
|
||||
/// to include initialization.
|
||||
/// Default: Depends on target.
|
||||
pub terminal: Option<String>,
|
||||
/// The command to execute.
|
||||
pub command: String,
|
||||
/// Pass to init the terminal session
|
||||
/// for when the terminal doesn't already exist.
|
||||
pub init: Option<InitTerminal>,
|
||||
}
|
||||
|
||||
/// Init a terminal on the server.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct InitTerminal {
|
||||
/// The shell command (eg `bash`) to init the shell.
|
||||
///
|
||||
/// This can also include args:
|
||||
/// `docker exec -it container sh`
|
||||
///
|
||||
/// Default: Configured on each Periphery
|
||||
pub command: Option<String>,
|
||||
/// Default: `Never`
|
||||
#[serde(default)]
|
||||
pub recreate: TerminalRecreateMode,
|
||||
}
|
||||
|
||||
/// Query to connect to a container exec session (interactive shell over websocket) on the given server.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ConnectContainerExecQuery {
|
||||
/// Server Id or name
|
||||
pub server: String,
|
||||
/// The container name
|
||||
pub container: String,
|
||||
/// The shell to use (eg. `sh` or `bash`)
|
||||
pub shell: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
pub recreate: Option<TerminalRecreateMode>,
|
||||
}
|
||||
|
||||
/// Query to connect to a container attach session (interactive shell over websocket) on the given server.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ConnectContainerAttachQuery {
|
||||
/// Server Id or name
|
||||
pub server: String,
|
||||
/// The container name
|
||||
pub container: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
pub recreate: Option<TerminalRecreateMode>,
|
||||
}
|
||||
|
||||
/// Execute a command in the given containers shell.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ExecuteContainerExecBody {
|
||||
/// Server Id or name
|
||||
pub server: String,
|
||||
/// The container name
|
||||
pub container: String,
|
||||
/// The shell to use (eg. `sh` or `bash`)
|
||||
pub shell: String,
|
||||
/// The command to execute.
|
||||
pub command: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
pub recreate: Option<TerminalRecreateMode>,
|
||||
}
|
||||
|
||||
/// Query to connect to a container exec session (interactive shell over websocket) on the given Deployment.
|
||||
/// This call will use access to the Deployment Terminal to permission the call.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ConnectDeploymentExecQuery {
|
||||
/// Deployment Id or name
|
||||
pub deployment: String,
|
||||
/// The shell to use (eg. `sh` or `bash`)
|
||||
pub shell: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
pub recreate: Option<TerminalRecreateMode>,
|
||||
}
|
||||
|
||||
/// Query to connect to a container attach session (interactive shell over websocket) on the given Deployment.
|
||||
/// This call will use access to the Deployment Terminal to permission the call.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ConnectDeploymentAttachQuery {
|
||||
/// Deployment Id or name
|
||||
pub deployment: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
pub recreate: Option<TerminalRecreateMode>,
|
||||
}
|
||||
|
||||
/// Execute a command in the given containers shell.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ExecuteDeploymentExecBody {
|
||||
/// Deployment Id or name
|
||||
pub deployment: String,
|
||||
/// The shell to use (eg. `sh` or `bash`)
|
||||
pub shell: String,
|
||||
/// The command to execute.
|
||||
pub command: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
pub recreate: Option<TerminalRecreateMode>,
|
||||
}
|
||||
|
||||
/// Query to connect to a container exec session (interactive shell over websocket) on the given Stack / service.
|
||||
/// This call will use access to the Stack Terminal to permission the call.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ConnectStackExecQuery {
|
||||
/// Stack Id or name
|
||||
pub stack: String,
|
||||
/// The service name to connect to
|
||||
pub service: String,
|
||||
/// The shell to use (eg. `sh` or `bash`)
|
||||
pub shell: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
pub recreate: Option<TerminalRecreateMode>,
|
||||
}
|
||||
|
||||
/// Query to connect to a container attach session (interactive shell over websocket) on the given Stack / service.
|
||||
/// This call will use access to the Stack Terminal to permission the call.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ConnectStackAttachQuery {
|
||||
/// Stack Id or name
|
||||
pub stack: String,
|
||||
/// The service name to attach to
|
||||
pub service: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
pub recreate: Option<TerminalRecreateMode>,
|
||||
}
|
||||
|
||||
/// Execute a command in the given containers shell.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ExecuteStackExecBody {
|
||||
/// Stack Id or name
|
||||
pub stack: String,
|
||||
/// The service name to connect to
|
||||
pub service: String,
|
||||
/// The shell to use (eg. `sh` or `bash`)
|
||||
pub shell: String,
|
||||
/// The command to execute.
|
||||
pub command: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
pub recreate: Option<TerminalRecreateMode>,
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ mod server;
|
||||
mod stack;
|
||||
mod sync;
|
||||
mod tags;
|
||||
mod terminal;
|
||||
mod user;
|
||||
mod user_group;
|
||||
mod variable;
|
||||
@@ -36,6 +37,7 @@ pub use server::*;
|
||||
pub use stack::*;
|
||||
pub use sync::*;
|
||||
pub use tags::*;
|
||||
pub use terminal::*;
|
||||
pub use user::*;
|
||||
pub use user_group::*;
|
||||
pub use variable::*;
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use derive_empty_traits::EmptyTraits;
|
||||
use resolver_api::Resolve;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::AsRefStr;
|
||||
use typeshare::typeshare;
|
||||
|
||||
use crate::entities::{
|
||||
NoData,
|
||||
server::{_PartialServerConfig, Server, ServerQuery},
|
||||
server::{_PartialServerConfig, Server},
|
||||
update::Update,
|
||||
};
|
||||
|
||||
@@ -132,102 +130,6 @@ pub struct CreateNetwork {
|
||||
|
||||
//
|
||||
|
||||
/// Configures the behavior of [CreateTerminal] if the
|
||||
/// specified terminal name already exists.
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, Default, Serialize, Deserialize, AsRefStr,
|
||||
)]
|
||||
pub enum TerminalRecreateMode {
|
||||
/// Never kill the old terminal if it already exists.
|
||||
/// If the command is different, returns error.
|
||||
#[default]
|
||||
Never,
|
||||
/// Always kill the old terminal and create new one
|
||||
Always,
|
||||
/// Only kill and recreate if the command is different.
|
||||
DifferentCommand,
|
||||
}
|
||||
|
||||
/// Create a terminal on the server.
|
||||
/// Response: [NoData]
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(KomodoWriteRequest)]
|
||||
#[response(NoData)]
|
||||
#[error(serror::Error)]
|
||||
pub struct CreateTerminal {
|
||||
/// Server Id or name
|
||||
pub server: String,
|
||||
/// The name of the terminal on the server to create.
|
||||
pub name: String,
|
||||
/// The shell command (eg `bash`) to init the shell.
|
||||
///
|
||||
/// This can also include args:
|
||||
/// `docker exec -it container sh`
|
||||
///
|
||||
/// Default: Configured on each Periphery
|
||||
pub command: Option<String>,
|
||||
/// Default: `Never`
|
||||
#[serde(default)]
|
||||
pub recreate: TerminalRecreateMode,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
/// Delete a terminal on the server.
|
||||
/// Response: [NoData]
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(KomodoWriteRequest)]
|
||||
#[response(NoData)]
|
||||
#[error(serror::Error)]
|
||||
pub struct DeleteTerminal {
|
||||
/// Server Id or name
|
||||
pub server: String,
|
||||
/// The name of the terminal on the server to delete.
|
||||
pub terminal: String,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
/// Delete all terminals on the server.
|
||||
/// Response: [NoData]
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(KomodoWriteRequest)]
|
||||
#[response(NoData)]
|
||||
#[error(serror::Error)]
|
||||
pub struct DeleteAllTerminals {
|
||||
/// Server Id or name
|
||||
pub server: String,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
/// Delete all terminals on many or all Servers.
|
||||
/// Response: [NoData]
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(KomodoWriteRequest)]
|
||||
#[response(NoData)]
|
||||
#[error(serror::Error)]
|
||||
pub struct BatchDeleteAllTerminals {
|
||||
/// optional structured query to filter servers.
|
||||
#[serde(default)]
|
||||
pub query: ServerQuery,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
/// Updates the Server with an explicit Public Key.
|
||||
/// Response: [Update]
|
||||
#[typeshare]
|
||||
|
||||
100
client/core/rs/src/api/write/terminal.rs
Normal file
100
client/core/rs/src/api/write/terminal.rs
Normal file
@@ -0,0 +1,100 @@
|
||||
use derive_empty_traits::EmptyTraits;
|
||||
use resolver_api::Resolve;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
use crate::entities::{
|
||||
NoData,
|
||||
server::ServerQuery,
|
||||
terminal::{
|
||||
ContainerTerminalMode, TerminalRecreateMode, TerminalTarget,
|
||||
},
|
||||
};
|
||||
|
||||
use super::KomodoWriteRequest;
|
||||
|
||||
//
|
||||
|
||||
/// Create a Terminal.
|
||||
/// Requires minimum Read + Terminal permission on the target Resource.
|
||||
/// Response: [NoData]
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Debug, Clone, Serialize, Deserialize, Resolve, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(KomodoWriteRequest)]
|
||||
#[response(NoData)]
|
||||
#[error(serror::Error)]
|
||||
pub struct CreateTerminal {
|
||||
/// A name for the Terminal session.
|
||||
pub name: String,
|
||||
/// The target to create terminal for
|
||||
pub target: TerminalTarget,
|
||||
/// The shell command (eg `bash`) to init the shell.
|
||||
///
|
||||
/// Default:
|
||||
/// - Server: Configured on each Periphery
|
||||
/// - ContainerExec: `sh`
|
||||
/// - Attach: unused
|
||||
pub command: Option<String>,
|
||||
/// For container terminals, choose 'exec' or 'attach'.
|
||||
///
|
||||
/// Default
|
||||
/// - Server: ignored
|
||||
/// - Container / Stack / Deployment: `exec`
|
||||
pub mode: Option<ContainerTerminalMode>,
|
||||
/// Default: `Never`
|
||||
#[serde(default)]
|
||||
pub recreate: TerminalRecreateMode,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
/// Delete a terminal.
|
||||
/// Response: [NoData]
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(KomodoWriteRequest)]
|
||||
#[response(NoData)]
|
||||
#[error(serror::Error)]
|
||||
pub struct DeleteTerminal {
|
||||
/// Server / Container / Stack / Deployment
|
||||
pub target: TerminalTarget,
|
||||
/// The name of the Terminal to delete.
|
||||
pub terminal: String,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
/// Delete all Terminals on the Server.
|
||||
/// Response: [NoData]
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(KomodoWriteRequest)]
|
||||
#[response(NoData)]
|
||||
#[error(serror::Error)]
|
||||
pub struct DeleteAllTerminals {
|
||||
/// Server Id or name
|
||||
pub server: String,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
/// Delete all terminals on many or all Servers.
|
||||
/// Response: [NoData]
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits,
|
||||
)]
|
||||
#[empty_traits(KomodoWriteRequest)]
|
||||
#[response(NoData)]
|
||||
#[error(serror::Error)]
|
||||
pub struct BatchDeleteAllTerminals {
|
||||
/// Optional structured query to filter servers.
|
||||
#[serde(default)]
|
||||
pub query: ServerQuery,
|
||||
}
|
||||
@@ -66,6 +66,8 @@ pub mod stats;
|
||||
pub mod sync;
|
||||
/// Subtypes of [Tag][tag::Tag].
|
||||
pub mod tag;
|
||||
|
||||
pub mod terminal;
|
||||
/// Subtypes of [ResourcesToml][toml::ResourcesToml].
|
||||
pub mod toml;
|
||||
/// Subtypes of [Update][update::Update].
|
||||
@@ -605,28 +607,6 @@ pub struct RepoExecutionResponse {
|
||||
pub commit_message: Option<String>,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Hash,
|
||||
Default,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Display,
|
||||
EnumString,
|
||||
)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
pub enum ContainerTerminalMode {
|
||||
#[default]
|
||||
Exec,
|
||||
Attach,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Debug,
|
||||
|
||||
@@ -246,6 +246,47 @@ impl PermissionLevel {
|
||||
}
|
||||
|
||||
impl PermissionLevelAndSpecifics {
|
||||
/// Elevates self by permissions in other:
|
||||
/// - If other.level > self.level, set self.level = other.level
|
||||
/// - If other includes more specifics, add them.
|
||||
pub fn elevate(&mut self, other: &impl HasLevelAndSpecific) {
|
||||
let other_level = other.level();
|
||||
if other_level > self.level {
|
||||
self.level = other_level;
|
||||
}
|
||||
self.specific.extend(other.specific().iter().cloned());
|
||||
}
|
||||
|
||||
/// Joins permissions in self with other to produce a new PermissionsLevelAndSpecifics:
|
||||
/// - If other.level > self.level, set self.level = other.level
|
||||
/// - If other includes more specifics, add them.
|
||||
pub fn join(
|
||||
&self,
|
||||
other: &impl HasLevelAndSpecific,
|
||||
) -> PermissionLevelAndSpecifics {
|
||||
let mut specific = self.specific.clone();
|
||||
specific.extend(other.specific().iter().cloned());
|
||||
PermissionLevelAndSpecifics {
|
||||
level: std::cmp::max(self.level, other.level()),
|
||||
specific,
|
||||
}
|
||||
}
|
||||
|
||||
/// Joins permissions in self with other to produce a new PermissionsLevelAndSpecifics:
|
||||
/// - If other.level > self.level, set self.level = other.level
|
||||
/// - If other includes more specifics, add them.
|
||||
pub fn join_permission(
|
||||
&self,
|
||||
other: &Permission,
|
||||
) -> PermissionLevelAndSpecifics {
|
||||
let mut specific = self.specific.clone();
|
||||
specific.extend(other.specific.iter().cloned());
|
||||
PermissionLevelAndSpecifics {
|
||||
level: std::cmp::max(self.level, other.level),
|
||||
specific,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true when self.level >= other.level,
|
||||
/// and has all required specific permissions.
|
||||
pub fn fulfills(
|
||||
@@ -332,3 +373,26 @@ impl PermissionLevelAndSpecifics {
|
||||
self.specific(SpecificPermission::Processes)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HasLevelAndSpecific {
|
||||
fn level(&self) -> PermissionLevel;
|
||||
fn specific(&self) -> &IndexSet<SpecificPermission>;
|
||||
}
|
||||
|
||||
impl HasLevelAndSpecific for Permission {
|
||||
fn level(&self) -> PermissionLevel {
|
||||
self.level
|
||||
}
|
||||
fn specific(&self) -> &IndexSet<SpecificPermission> {
|
||||
&self.specific
|
||||
}
|
||||
}
|
||||
|
||||
impl HasLevelAndSpecific for PermissionLevelAndSpecifics {
|
||||
fn level(&self) -> PermissionLevel {
|
||||
self.level
|
||||
}
|
||||
fn specific(&self) -> &IndexSet<SpecificPermission> {
|
||||
&self.specific
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::{
|
||||
deserializers::{
|
||||
option_string_list_deserializer, string_list_deserializer,
|
||||
},
|
||||
entities::{I64, MaintenanceWindow, Timelength},
|
||||
entities::{MaintenanceWindow, Timelength},
|
||||
};
|
||||
|
||||
use super::{
|
||||
@@ -364,62 +364,6 @@ pub struct PeripheryInformation {
|
||||
pub public_ip: Option<String>,
|
||||
}
|
||||
|
||||
/// Info about an active terminal on a server.
|
||||
/// Retrieve with [ListTerminals][crate::api::read::server::ListTerminals].
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Default, Debug, Clone)]
|
||||
pub struct TerminalInfo {
|
||||
/// The name of the terminal.
|
||||
pub name: String,
|
||||
/// The root program / args of the pty
|
||||
pub command: String,
|
||||
/// The size of the terminal history in memory.
|
||||
pub stored_size_kb: f64,
|
||||
/// When the Terminal was created.
|
||||
pub created_at: I64,
|
||||
}
|
||||
|
||||
/// Info about an active terminal on a server.
|
||||
/// Retrieve with [ListAllTerminals][crate::api::read::server::ListAllTerminals].
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Default, Debug, Clone)]
|
||||
pub struct TerminalInfoWithServer {
|
||||
/// The server id.
|
||||
pub server_id: String,
|
||||
/// The server name.
|
||||
pub server_name: String,
|
||||
/// The name of the terminal.
|
||||
pub name: String,
|
||||
/// The root program / args of the pty
|
||||
pub command: String,
|
||||
/// The size of the terminal history in memory.
|
||||
pub stored_size_kb: f64,
|
||||
/// When the Terminal was created in unix milliseconds.
|
||||
pub created_at: I64,
|
||||
}
|
||||
|
||||
impl TerminalInfoWithServer {
|
||||
pub fn from_terminal_info(
|
||||
server_id: impl Into<String>,
|
||||
server_name: impl Into<String>,
|
||||
TerminalInfo {
|
||||
name,
|
||||
command,
|
||||
stored_size_kb,
|
||||
created_at,
|
||||
}: TerminalInfo,
|
||||
) -> Self {
|
||||
Self {
|
||||
server_id: server_id.into(),
|
||||
server_name: server_name.into(),
|
||||
name,
|
||||
command,
|
||||
stored_size_kb,
|
||||
created_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Current pending actions on the server.
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Default)]
|
||||
|
||||
110
client/core/rs/src/entities/terminal.rs
Normal file
110
client/core/rs/src/entities/terminal.rs
Normal file
@@ -0,0 +1,110 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::AsRefStr;
|
||||
use typeshare::typeshare;
|
||||
|
||||
use crate::entities::I64;
|
||||
|
||||
/// Represents an active terminal on a server.
|
||||
/// Retrieve with [ListTerminals][crate::api::read::server::ListTerminals].
|
||||
#[typeshare]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Terminal {
|
||||
/// The name of the terminal.
|
||||
pub name: String,
|
||||
/// The target resource of the Terminal.
|
||||
pub target: TerminalTarget,
|
||||
/// The command used to init the shell.
|
||||
pub command: String,
|
||||
/// The size of the terminal history in memory.
|
||||
pub stored_size_kb: f64,
|
||||
/// When the Terminal was created.
|
||||
/// Unix timestamp milliseconds.
|
||||
pub created_at: I64,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize,
|
||||
)]
|
||||
#[serde(tag = "type", content = "params")]
|
||||
pub enum TerminalTarget {
|
||||
Server {
|
||||
server: Option<String>,
|
||||
},
|
||||
Container {
|
||||
server: String,
|
||||
container: String,
|
||||
},
|
||||
Stack {
|
||||
stack: String,
|
||||
service: Option<String>,
|
||||
},
|
||||
Deployment {
|
||||
deployment: String,
|
||||
},
|
||||
}
|
||||
|
||||
impl TerminalTarget {
|
||||
// Checks for target match in a fixed server context.
|
||||
pub fn matches_on_server(&self, other: &TerminalTarget) -> bool {
|
||||
match (self, other) {
|
||||
(
|
||||
TerminalTarget::Server { .. },
|
||||
TerminalTarget::Server { .. },
|
||||
) => true,
|
||||
(
|
||||
TerminalTarget::Container {
|
||||
container: target, ..
|
||||
},
|
||||
TerminalTarget::Container { container, .. },
|
||||
) => target == container,
|
||||
(
|
||||
TerminalTarget::Stack { stack: target, .. },
|
||||
TerminalTarget::Stack { stack, .. },
|
||||
) => target == stack,
|
||||
(
|
||||
TerminalTarget::Deployment { deployment: target },
|
||||
TerminalTarget::Deployment { deployment },
|
||||
) => target == deployment,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// JSON structure to send new terminal window dimensions
|
||||
#[typeshare]
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct ResizeDimensions {
|
||||
pub rows: u16,
|
||||
pub cols: u16,
|
||||
}
|
||||
|
||||
/// Specify the container terminal mode (exec or attach)
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, Default, Serialize, Deserialize, AsRefStr,
|
||||
)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
pub enum ContainerTerminalMode {
|
||||
#[default]
|
||||
Exec,
|
||||
Attach,
|
||||
}
|
||||
|
||||
/// Configures the behavior of [CreateTerminal] if the
|
||||
/// specified terminal name already exists.
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, Default, Serialize, Deserialize, AsRefStr,
|
||||
)]
|
||||
pub enum TerminalRecreateMode {
|
||||
/// Never kill the old terminal if it already exists.
|
||||
/// If the init command is different, returns error.
|
||||
#[default]
|
||||
Never,
|
||||
/// Always kill the old terminal and create new one
|
||||
Always,
|
||||
/// Only kill and recreate if the command is different.
|
||||
DifferentCommand,
|
||||
}
|
||||
@@ -9,7 +9,10 @@ use tokio_tungstenite::{
|
||||
};
|
||||
use typeshare::typeshare;
|
||||
|
||||
use crate::{KomodoClient, api::write::TerminalRecreateMode};
|
||||
use crate::{
|
||||
KomodoClient, api::terminal::ConnectTerminalQuery,
|
||||
entities::terminal::TerminalRecreateMode,
|
||||
};
|
||||
|
||||
pub mod update;
|
||||
|
||||
@@ -36,13 +39,12 @@ impl WsLoginMessage {
|
||||
impl KomodoClient {
|
||||
pub async fn connect_terminal_websocket(
|
||||
&self,
|
||||
server: &str,
|
||||
terminal: &str,
|
||||
query: &ConnectTerminalQuery,
|
||||
) -> anyhow::Result<WebSocketStream<MaybeTlsStream<TcpStream>>> {
|
||||
self
|
||||
.connect_login_user_websocket(
|
||||
"/terminal",
|
||||
Some(&format!("server={server}&terminal={terminal}")),
|
||||
Some(&serde_qs::to_string(query)?),
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -52,13 +54,12 @@ impl KomodoClient {
|
||||
server: &str,
|
||||
container: &str,
|
||||
shell: &str,
|
||||
recreate: Option<TerminalRecreateMode>,
|
||||
recreate: TerminalRecreateMode,
|
||||
) -> anyhow::Result<WebSocketStream<MaybeTlsStream<TcpStream>>> {
|
||||
let mut query =
|
||||
format!("server={server}&container={container}&shell={shell}");
|
||||
if let Some(recreate) = recreate {
|
||||
let _ = write!(&mut query, "&recreate={}", recreate.as_ref());
|
||||
}
|
||||
let query = format!(
|
||||
"server={server}&container={container}&shell={shell}&recreate={}",
|
||||
recreate.as_ref()
|
||||
);
|
||||
self
|
||||
.connect_login_user_websocket(
|
||||
"/container/terminal",
|
||||
@@ -71,12 +72,12 @@ impl KomodoClient {
|
||||
&self,
|
||||
server: &str,
|
||||
container: &str,
|
||||
recreate: Option<TerminalRecreateMode>,
|
||||
recreate: TerminalRecreateMode,
|
||||
) -> anyhow::Result<WebSocketStream<MaybeTlsStream<TcpStream>>> {
|
||||
let mut query = format!("server={server}&container={container}");
|
||||
if let Some(recreate) = recreate {
|
||||
let _ = write!(&mut query, "&recreate={}", recreate.as_ref());
|
||||
}
|
||||
let query = format!(
|
||||
"server={server}&container={container}&recreate={}",
|
||||
recreate.as_ref()
|
||||
);
|
||||
self
|
||||
.connect_login_user_websocket(
|
||||
"/container/terminal/attach",
|
||||
|
||||
@@ -5,12 +5,7 @@ import {
|
||||
UserResponses,
|
||||
WriteResponses,
|
||||
} from "./responses.js";
|
||||
import {
|
||||
terminal_methods,
|
||||
ConnectExecQuery,
|
||||
ExecuteExecBody,
|
||||
TerminalCallbacks,
|
||||
} from "./terminal.js";
|
||||
import { terminal_methods, TerminalCallbacks } from "./terminal.js";
|
||||
import {
|
||||
AuthRequest,
|
||||
BatchExecutionResponse,
|
||||
@@ -28,7 +23,7 @@ import {
|
||||
|
||||
export * as Types from "./types.js";
|
||||
|
||||
export type { ConnectExecQuery, ExecuteExecBody, TerminalCallbacks };
|
||||
export type { TerminalCallbacks };
|
||||
|
||||
export type InitOptions =
|
||||
| { type: "jwt"; params: { jwt: string } }
|
||||
@@ -327,25 +322,8 @@ export function KomodoClient(url: string, options: InitOptions) {
|
||||
}
|
||||
};
|
||||
|
||||
const {
|
||||
connect_terminal,
|
||||
execute_terminal,
|
||||
execute_terminal_stream,
|
||||
connect_exec,
|
||||
connect_attach,
|
||||
connect_container_exec,
|
||||
connect_container_attach,
|
||||
execute_container_exec,
|
||||
execute_container_exec_stream,
|
||||
connect_deployment_exec,
|
||||
connect_deployment_attach,
|
||||
execute_deployment_exec,
|
||||
execute_deployment_exec_stream,
|
||||
connect_stack_exec,
|
||||
connect_stack_attach,
|
||||
execute_stack_exec,
|
||||
execute_stack_exec_stream,
|
||||
} = terminal_methods(url, state);
|
||||
const { connect_terminal, execute_terminal, execute_terminal_stream } =
|
||||
terminal_methods(url, state);
|
||||
|
||||
return {
|
||||
/**
|
||||
@@ -454,9 +432,18 @@ export function KomodoClient(url: string, options: InitOptions) {
|
||||
* ```ts
|
||||
* await komodo.execute_terminal(
|
||||
* {
|
||||
* server: "my-server",
|
||||
* target: {
|
||||
* type: "Server",
|
||||
* params: {
|
||||
* server: "my-server"
|
||||
* }
|
||||
* },
|
||||
* terminal: "name",
|
||||
* command: 'for i in {1..3}; do echo "$i"; sleep 1; done',
|
||||
* init: {
|
||||
* command: "bash",
|
||||
* recreate: Types.TerminalRecreateMode.Always
|
||||
* }
|
||||
* },
|
||||
* {
|
||||
* onLine: (line) => console.log(line),
|
||||
@@ -479,9 +466,18 @@ export function KomodoClient(url: string, options: InitOptions) {
|
||||
*
|
||||
* ```ts
|
||||
* const stream = await komodo.execute_terminal_stream({
|
||||
* server: "my-server",
|
||||
* target: {
|
||||
* type: "Server",
|
||||
* params: {
|
||||
* server: "my-server"
|
||||
* }
|
||||
* },
|
||||
* terminal: "name",
|
||||
* command: 'for i in {1..3}; do echo "$i"; sleep 1; done',
|
||||
* init: {
|
||||
* command: "bash",
|
||||
* recreate: Types.TerminalRecreateMode.Always
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* for await (const line of stream) {
|
||||
@@ -490,188 +486,5 @@ export function KomodoClient(url: string, options: InitOptions) {
|
||||
* ```
|
||||
*/
|
||||
execute_terminal_stream,
|
||||
/**
|
||||
* Subscribes to container exec io over websocket message,
|
||||
* for use with xtermjs. Can connect to container on a Server,
|
||||
* or associated with a Deployment or Stack.
|
||||
* Terminal permission on connecting resource required.
|
||||
*/
|
||||
connect_exec,
|
||||
/**
|
||||
* Subscribes to container attach io over websocket message,
|
||||
* for use with xtermjs. Can attach to container on a Server,
|
||||
* or associated with a Deployment or Stack.
|
||||
* Terminal permission on connecting resource required.
|
||||
*/
|
||||
connect_attach,
|
||||
/**
|
||||
* Subscribes to container exec io over websocket message,
|
||||
* for use with xtermjs. Can connect to Container on a Server.
|
||||
* Server Terminal permission required.
|
||||
*/
|
||||
connect_container_exec,
|
||||
/**
|
||||
* Subscribes to container attach io over websocket message,
|
||||
* for use with xtermjs. Can attach to Container on a Server.
|
||||
* Server Terminal permission required.
|
||||
*/
|
||||
connect_container_attach,
|
||||
/**
|
||||
* Executes a command on a given container,
|
||||
* and gives a callback to handle the output as it comes in.
|
||||
*
|
||||
* ```ts
|
||||
* await komodo.execute_container_exec(
|
||||
* {
|
||||
* server: "my-server",
|
||||
* container: "name",
|
||||
* shell: "bash",
|
||||
* command: 'for i in {1..3}; do echo "$i"; sleep 1; done',
|
||||
* },
|
||||
* {
|
||||
* onLine: (line) => console.log(line),
|
||||
* onFinish: (code) => console.log("Finished:", code),
|
||||
* }
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
execute_container_exec,
|
||||
/**
|
||||
* Executes a command on a given container,
|
||||
* and returns a stream to process the output as it comes in.
|
||||
*
|
||||
* Note. The final line of the stream will usually be
|
||||
* `__KOMODO_EXIT_CODE__:0`. The number
|
||||
* is the exit code of the command.
|
||||
*
|
||||
* If this line is NOT present, it means the stream
|
||||
* was terminated early, ie like running `exit`.
|
||||
*
|
||||
* ```ts
|
||||
* const stream = await komodo.execute_container_exec_stream({
|
||||
* server: "my-server",
|
||||
* container: "name",
|
||||
* shell: "bash",
|
||||
* command: 'for i in {1..3}; do echo "$i"; sleep 1; done',
|
||||
* });
|
||||
*
|
||||
* for await (const line of stream) {
|
||||
* console.log(line);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
execute_container_exec_stream,
|
||||
/**
|
||||
* Subscribes to deployment container exec io over websocket message,
|
||||
* for use with xtermjs. Can connect to Deployment container.
|
||||
* Deployment Terminal permission required.
|
||||
*/
|
||||
connect_deployment_exec,
|
||||
/**
|
||||
* Subscribes to deployment container attach io over websocket message,
|
||||
* for use with xtermjs. Can attach to Deployment container.
|
||||
* Deployment Terminal permission required.
|
||||
*/
|
||||
connect_deployment_attach,
|
||||
/**
|
||||
* Executes a command on a given deployment container,
|
||||
* and gives a callback to handle the output as it comes in.
|
||||
*
|
||||
* ```ts
|
||||
* await komodo.execute_deployment_exec(
|
||||
* {
|
||||
* deployment: "my-deployment",
|
||||
* shell: "bash",
|
||||
* command: 'for i in {1..3}; do echo "$i"; sleep 1; done',
|
||||
* },
|
||||
* {
|
||||
* onLine: (line) => console.log(line),
|
||||
* onFinish: (code) => console.log("Finished:", code),
|
||||
* }
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
execute_deployment_exec,
|
||||
/**
|
||||
* Executes a command on a given deployment container,
|
||||
* and returns a stream to process the output as it comes in.
|
||||
*
|
||||
* Note. The final line of the stream will usually be
|
||||
* `__KOMODO_EXIT_CODE__:0`. The number
|
||||
* is the exit code of the command.
|
||||
*
|
||||
* If this line is NOT present, it means the stream
|
||||
* was terminated early, ie like running `exit`.
|
||||
*
|
||||
* ```ts
|
||||
* const stream = await komodo.execute_deployment_exec_stream({
|
||||
* deployment: "my-deployment",
|
||||
* shell: "bash",
|
||||
* command: 'for i in {1..3}; do echo "$i"; sleep 1; done',
|
||||
* });
|
||||
*
|
||||
* for await (const line of stream) {
|
||||
* console.log(line);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
execute_deployment_exec_stream,
|
||||
/**
|
||||
* Subscribes to container exec io over websocket message,
|
||||
* for use with xtermjs. Can connect to Stack service container.
|
||||
* Stack Terminal permission required.
|
||||
*/
|
||||
connect_stack_exec,
|
||||
/**
|
||||
* Subscribes to container attach io over websocket message,
|
||||
* for use with xtermjs. Can attach to Stack service container.
|
||||
* Stack Terminal permission required.
|
||||
*/
|
||||
connect_stack_attach,
|
||||
/**
|
||||
* Executes a command on a given stack service container,
|
||||
* and gives a callback to handle the output as it comes in.
|
||||
*
|
||||
* ```ts
|
||||
* await komodo.execute_stack_exec(
|
||||
* {
|
||||
* stack: "my-stack",
|
||||
* service: "database"
|
||||
* shell: "bash",
|
||||
* command: 'for i in {1..3}; do echo "$i"; sleep 1; done',
|
||||
* },
|
||||
* {
|
||||
* onLine: (line) => console.log(line),
|
||||
* onFinish: (code) => console.log("Finished:", code),
|
||||
* }
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
execute_stack_exec,
|
||||
/**
|
||||
* Executes a command on a given stack service container,
|
||||
* and returns a stream to process the output as it comes in.
|
||||
*
|
||||
* Note. The final line of the stream will usually be
|
||||
* `__KOMODO_EXIT_CODE__:0`. The number
|
||||
* is the exit code of the command.
|
||||
*
|
||||
* If this line is NOT present, it means the stream
|
||||
* was terminated early, ie like running `exit`.
|
||||
*
|
||||
* ```ts
|
||||
* const stream = await komodo.execute_stack_exec_stream({
|
||||
* stack: "my-stack",
|
||||
* service: "service1",
|
||||
* shell: "bash",
|
||||
* command: 'for i in {1..3}; do echo "$i"; sleep 1; done',
|
||||
* });
|
||||
*
|
||||
* for await (const line of stream) {
|
||||
* console.log(line);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
execute_stack_exec_stream,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ export type ReadResponses = {
|
||||
ListServers: Types.ListServersResponse;
|
||||
ListFullServers: Types.ListFullServersResponse;
|
||||
ListTerminals: Types.ListTerminalsResponse;
|
||||
ListAllTerminals: Types.ListAllTerminalsResponse;
|
||||
|
||||
// ==== DOCKER ====
|
||||
GetDockerContainersSummary: Types.GetDockerContainersSummaryResponse;
|
||||
@@ -217,10 +216,6 @@ export type WriteResponses = {
|
||||
UpdateServer: Types.Server;
|
||||
RenameServer: Types.Update;
|
||||
CreateNetwork: Types.Update;
|
||||
CreateTerminal: Types.NoData;
|
||||
DeleteTerminal: Types.NoData;
|
||||
DeleteAllTerminals: Types.NoData;
|
||||
BatchDeleteAllTerminals: Types.NoData;
|
||||
UpdateServerPublicKey: Types.Update;
|
||||
RotateServerKeys: Types.Update;
|
||||
|
||||
@@ -296,6 +291,12 @@ export type WriteResponses = {
|
||||
WriteSyncFileContents: Types.Update;
|
||||
RefreshResourceSyncPending: Types.ResourceSync;
|
||||
|
||||
// ==== TERMINAL ====
|
||||
CreateTerminal: Types.NoData;
|
||||
DeleteTerminal: Types.NoData;
|
||||
DeleteAllTerminals: Types.NoData;
|
||||
BatchDeleteAllTerminals: Types.NoData;
|
||||
|
||||
// ==== TAG ====
|
||||
CreateTag: Types.Tag;
|
||||
DeleteTag: Types.Tag;
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
import { ClientState } from "./lib";
|
||||
import { ClientState, Types } from "./lib";
|
||||
import {
|
||||
ConnectContainerAttachQuery,
|
||||
ConnectContainerExecQuery,
|
||||
ConnectDeploymentAttachQuery,
|
||||
ConnectDeploymentExecQuery,
|
||||
ConnectStackAttachQuery,
|
||||
ConnectStackExecQuery,
|
||||
ConnectTerminalQuery,
|
||||
ExecuteContainerExecBody,
|
||||
ExecuteDeploymentExecBody,
|
||||
ExecuteStackExecBody,
|
||||
ExecuteTerminalBody,
|
||||
TerminalTarget,
|
||||
WsLoginMessage,
|
||||
} from "./types";
|
||||
|
||||
@@ -21,48 +13,6 @@ export type TerminalCallbacks = {
|
||||
on_close?: () => void;
|
||||
};
|
||||
|
||||
export type ConnectExecQuery =
|
||||
| {
|
||||
type: "container";
|
||||
query: ConnectContainerExecQuery;
|
||||
}
|
||||
| {
|
||||
type: "deployment";
|
||||
query: ConnectDeploymentExecQuery;
|
||||
}
|
||||
| {
|
||||
type: "stack";
|
||||
query: ConnectStackExecQuery;
|
||||
};
|
||||
|
||||
export type ConnectAttachQuery =
|
||||
| {
|
||||
type: "container";
|
||||
query: ConnectContainerAttachQuery;
|
||||
}
|
||||
| {
|
||||
type: "deployment";
|
||||
query: ConnectDeploymentAttachQuery;
|
||||
}
|
||||
| {
|
||||
type: "stack";
|
||||
query: ConnectStackAttachQuery;
|
||||
};
|
||||
|
||||
export type ExecuteExecBody =
|
||||
| {
|
||||
type: "container";
|
||||
body: ExecuteContainerExecBody;
|
||||
}
|
||||
| {
|
||||
type: "deployment";
|
||||
body: ExecuteDeploymentExecBody;
|
||||
}
|
||||
| {
|
||||
type: "stack";
|
||||
body: ExecuteStackExecBody;
|
||||
};
|
||||
|
||||
export type ExecuteCallbacks = {
|
||||
onLine?: (line: string) => void | Promise<void>;
|
||||
onFinish?: (code: string) => void | Promise<void>;
|
||||
@@ -70,7 +20,7 @@ export type ExecuteCallbacks = {
|
||||
|
||||
export const terminal_methods = (url: string, state: ClientState) => {
|
||||
const connect_terminal = ({
|
||||
query,
|
||||
query: { target, terminal, init },
|
||||
on_message,
|
||||
on_login,
|
||||
on_open,
|
||||
@@ -78,9 +28,19 @@ export const terminal_methods = (url: string, state: ClientState) => {
|
||||
}: {
|
||||
query: ConnectTerminalQuery;
|
||||
} & TerminalCallbacks) => {
|
||||
const url_query = new URLSearchParams(
|
||||
query as any as Record<string, string>
|
||||
).toString();
|
||||
let url_query = connect_terminal_target_query(target);
|
||||
if (terminal) {
|
||||
url_query += `&terminal=${terminal}`;
|
||||
}
|
||||
if (init?.command) {
|
||||
url_query += `&init[command]=${init.command}`;
|
||||
}
|
||||
if (init?.recreate) {
|
||||
url_query += `&init[recreate]=${init.recreate}`;
|
||||
}
|
||||
if (init?.mode) {
|
||||
url_query += `&init[mode]=${init.mode}`;
|
||||
}
|
||||
const ws = new WebSocket(
|
||||
url.replace("http", "ws") + "/ws/terminal?" + url_query
|
||||
);
|
||||
@@ -140,200 +100,6 @@ export const terminal_methods = (url: string, state: ClientState) => {
|
||||
const execute_terminal_stream = (request: ExecuteTerminalBody) =>
|
||||
execute_stream("/terminal/execute", request);
|
||||
|
||||
const connect_container_exec = ({
|
||||
query,
|
||||
...callbacks
|
||||
}: {
|
||||
query: ConnectContainerExecQuery;
|
||||
} & TerminalCallbacks) =>
|
||||
connect_exec({ query: { type: "container", query }, ...callbacks });
|
||||
|
||||
const connect_deployment_exec = ({
|
||||
query,
|
||||
...callbacks
|
||||
}: {
|
||||
query: ConnectDeploymentExecQuery;
|
||||
} & TerminalCallbacks) =>
|
||||
connect_exec({ query: { type: "deployment", query }, ...callbacks });
|
||||
|
||||
const connect_stack_exec = ({
|
||||
query,
|
||||
...callbacks
|
||||
}: {
|
||||
query: ConnectStackExecQuery;
|
||||
} & TerminalCallbacks) =>
|
||||
connect_exec({ query: { type: "stack", query }, ...callbacks });
|
||||
|
||||
const connect_exec = ({
|
||||
query: { type, query },
|
||||
on_message,
|
||||
on_login,
|
||||
on_open,
|
||||
on_close,
|
||||
}: {
|
||||
query: ConnectExecQuery;
|
||||
} & TerminalCallbacks) => {
|
||||
const url_query = new URLSearchParams(
|
||||
query as any as Record<string, string>
|
||||
).toString();
|
||||
const ws = new WebSocket(
|
||||
url.replace("http", "ws") + `/ws/${type}/terminal?` + url_query
|
||||
);
|
||||
// Handle login on websocket open
|
||||
ws.onopen = () => {
|
||||
const login_msg: WsLoginMessage = state.jwt
|
||||
? {
|
||||
type: "Jwt",
|
||||
params: {
|
||||
jwt: state.jwt,
|
||||
},
|
||||
}
|
||||
: {
|
||||
type: "ApiKeys",
|
||||
params: {
|
||||
key: state.key!,
|
||||
secret: state.secret!,
|
||||
},
|
||||
};
|
||||
ws.send(JSON.stringify(login_msg));
|
||||
on_open?.();
|
||||
};
|
||||
|
||||
ws.onmessage = (e) => {
|
||||
if (e.data == "LOGGED_IN") {
|
||||
ws.binaryType = "arraybuffer";
|
||||
ws.onmessage = (e) => on_message?.(e);
|
||||
on_login?.();
|
||||
return;
|
||||
} else {
|
||||
on_message?.(e);
|
||||
}
|
||||
};
|
||||
|
||||
ws.onclose = () => on_close?.();
|
||||
|
||||
return ws;
|
||||
};
|
||||
|
||||
const connect_container_attach = ({
|
||||
query,
|
||||
...callbacks
|
||||
}: {
|
||||
query: ConnectContainerAttachQuery;
|
||||
} & TerminalCallbacks) =>
|
||||
connect_attach({ query: { type: "container", query }, ...callbacks });
|
||||
|
||||
const connect_deployment_attach = ({
|
||||
query,
|
||||
...callbacks
|
||||
}: {
|
||||
query: ConnectDeploymentAttachQuery;
|
||||
} & TerminalCallbacks) =>
|
||||
connect_attach({ query: { type: "deployment", query }, ...callbacks });
|
||||
|
||||
const connect_stack_attach = ({
|
||||
query,
|
||||
...callbacks
|
||||
}: {
|
||||
query: ConnectStackAttachQuery;
|
||||
} & TerminalCallbacks) =>
|
||||
connect_attach({ query: { type: "stack", query }, ...callbacks });
|
||||
|
||||
const connect_attach = ({
|
||||
query: { type, query },
|
||||
on_message,
|
||||
on_login,
|
||||
on_open,
|
||||
on_close,
|
||||
}: {
|
||||
query: ConnectAttachQuery;
|
||||
} & TerminalCallbacks) => {
|
||||
const url_query = new URLSearchParams(
|
||||
query as any as Record<string, string>
|
||||
).toString();
|
||||
const ws = new WebSocket(
|
||||
url.replace("http", "ws") + `/ws/${type}/terminal/attach?` + url_query
|
||||
);
|
||||
// Handle login on websocket open
|
||||
ws.onopen = () => {
|
||||
const login_msg: WsLoginMessage = state.jwt
|
||||
? {
|
||||
type: "Jwt",
|
||||
params: {
|
||||
jwt: state.jwt,
|
||||
},
|
||||
}
|
||||
: {
|
||||
type: "ApiKeys",
|
||||
params: {
|
||||
key: state.key!,
|
||||
secret: state.secret!,
|
||||
},
|
||||
};
|
||||
ws.send(JSON.stringify(login_msg));
|
||||
on_open?.();
|
||||
};
|
||||
|
||||
ws.onmessage = (e) => {
|
||||
if (e.data == "LOGGED_IN") {
|
||||
ws.binaryType = "arraybuffer";
|
||||
ws.onmessage = (e) => on_message?.(e);
|
||||
on_login?.();
|
||||
return;
|
||||
} else {
|
||||
on_message?.(e);
|
||||
}
|
||||
};
|
||||
|
||||
ws.onclose = () => on_close?.();
|
||||
|
||||
return ws;
|
||||
};
|
||||
|
||||
const execute_container_exec = (
|
||||
body: ExecuteContainerExecBody,
|
||||
callbacks?: ExecuteCallbacks
|
||||
) => execute_exec({ type: "container", body }, callbacks);
|
||||
|
||||
const execute_deployment_exec = (
|
||||
body: ExecuteDeploymentExecBody,
|
||||
callbacks?: ExecuteCallbacks
|
||||
) => execute_exec({ type: "deployment", body }, callbacks);
|
||||
|
||||
const execute_stack_exec = (
|
||||
body: ExecuteStackExecBody,
|
||||
callbacks?: ExecuteCallbacks
|
||||
) => execute_exec({ type: "stack", body }, callbacks);
|
||||
|
||||
const execute_exec = async (
|
||||
request: ExecuteExecBody,
|
||||
callbacks?: ExecuteCallbacks
|
||||
) => {
|
||||
const stream = await execute_exec_stream(request);
|
||||
for await (const line of stream) {
|
||||
if (line.startsWith("__KOMODO_EXIT_CODE")) {
|
||||
await callbacks?.onFinish?.(line.split(":")[1]);
|
||||
return;
|
||||
} else {
|
||||
await callbacks?.onLine?.(line);
|
||||
}
|
||||
}
|
||||
// This is hit if no __KOMODO_EXIT_CODE is sent, ie early exit
|
||||
await callbacks?.onFinish?.("Early exit without code");
|
||||
};
|
||||
|
||||
const execute_container_exec_stream = (body: ExecuteContainerExecBody) =>
|
||||
execute_exec_stream({ type: "container", body });
|
||||
|
||||
const execute_deployment_exec_stream = (body: ExecuteDeploymentExecBody) =>
|
||||
execute_exec_stream({ type: "deployment", body });
|
||||
|
||||
const execute_stack_exec_stream = (body: ExecuteStackExecBody) =>
|
||||
execute_exec_stream({ type: "stack", body });
|
||||
|
||||
const execute_exec_stream = (request: ExecuteExecBody) =>
|
||||
execute_stream(`/terminal/execute/${request.type}`, request.body);
|
||||
|
||||
const execute_stream = (path: string, request: any) =>
|
||||
new Promise<AsyncIterable<string>>(async (res, rej) => {
|
||||
try {
|
||||
@@ -412,19 +178,25 @@ export const terminal_methods = (url: string, state: ClientState) => {
|
||||
connect_terminal,
|
||||
execute_terminal,
|
||||
execute_terminal_stream,
|
||||
connect_exec,
|
||||
connect_attach,
|
||||
connect_container_exec,
|
||||
connect_container_attach,
|
||||
execute_container_exec,
|
||||
execute_container_exec_stream,
|
||||
connect_deployment_exec,
|
||||
connect_deployment_attach,
|
||||
execute_deployment_exec,
|
||||
execute_deployment_exec_stream,
|
||||
connect_stack_exec,
|
||||
connect_stack_attach,
|
||||
execute_stack_exec,
|
||||
execute_stack_exec_stream,
|
||||
};
|
||||
};
|
||||
|
||||
const connect_terminal_target_query = (target: TerminalTarget) => {
|
||||
const base = `target[type]=${target.type}&`;
|
||||
switch (target.type) {
|
||||
case "Server":
|
||||
return base + `target[params][server]=${target.params.server}`;
|
||||
case "Container":
|
||||
return (
|
||||
base +
|
||||
`target[params][server]=${target.params.server}&target[params][container]=${target.params.container}`
|
||||
);
|
||||
case "Stack":
|
||||
return (
|
||||
base +
|
||||
`target[params][stack]=${target.params.stack}&target[params][service]=${target.params.service}`
|
||||
);
|
||||
case "Deployment":
|
||||
return base + `target[params][deployment]=${target.params.deployment}`;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3554,27 +3554,6 @@ export interface ContainerListItem {
|
||||
|
||||
export type ListAllDockerContainersResponse = ContainerListItem[];
|
||||
|
||||
/**
|
||||
* Info about an active terminal on a server.
|
||||
* Retrieve with [ListAllTerminals][crate::api::read::server::ListAllTerminals].
|
||||
*/
|
||||
export interface TerminalInfoWithServer {
|
||||
/** The server id. */
|
||||
server_id: string;
|
||||
/** The server name. */
|
||||
server_name: string;
|
||||
/** The name of the terminal. */
|
||||
name: string;
|
||||
/** The root program / args of the pty */
|
||||
command: string;
|
||||
/** The size of the terminal history in memory. */
|
||||
stored_size_kb: number;
|
||||
/** When the Terminal was created in unix milliseconds. */
|
||||
created_at: I64;
|
||||
}
|
||||
|
||||
export type ListAllTerminalsResponse = TerminalInfoWithServer[];
|
||||
|
||||
/** An api key used to authenticate requests via request headers. */
|
||||
export interface ApiKey {
|
||||
/** Unique key associated with secret */
|
||||
@@ -4110,22 +4089,43 @@ export type ListSystemProcessesResponse = SystemProcess[];
|
||||
|
||||
export type ListTagsResponse = Tag[];
|
||||
|
||||
export type TerminalTarget =
|
||||
| { type: "Server", params: {
|
||||
server?: string;
|
||||
}}
|
||||
| { type: "Container", params: {
|
||||
server: string;
|
||||
container: string;
|
||||
}}
|
||||
| { type: "Stack", params: {
|
||||
stack: string;
|
||||
service?: string;
|
||||
}}
|
||||
| { type: "Deployment", params: {
|
||||
deployment: string;
|
||||
}};
|
||||
|
||||
/**
|
||||
* Info about an active terminal on a server.
|
||||
* Represents an active terminal on a server.
|
||||
* Retrieve with [ListTerminals][crate::api::read::server::ListTerminals].
|
||||
*/
|
||||
export interface TerminalInfo {
|
||||
export interface Terminal {
|
||||
/** The name of the terminal. */
|
||||
name: string;
|
||||
/** The root program / args of the pty */
|
||||
/** The target resource of the Terminal. */
|
||||
target: TerminalTarget;
|
||||
/** The command used to init the shell. */
|
||||
command: string;
|
||||
/** The size of the terminal history in memory. */
|
||||
stored_size_kb: number;
|
||||
/** When the Terminal was created. */
|
||||
/**
|
||||
* When the Terminal was created.
|
||||
* Unix timestamp milliseconds.
|
||||
*/
|
||||
created_at: I64;
|
||||
}
|
||||
|
||||
export type ListTerminalsResponse = TerminalInfo[];
|
||||
export type ListTerminalsResponse = Terminal[];
|
||||
|
||||
export type ListUserGroupsResponse = UserGroup[];
|
||||
|
||||
@@ -4383,7 +4383,7 @@ export interface BatchCloneRepo {
|
||||
* Response: [NoData]
|
||||
*/
|
||||
export interface BatchDeleteAllTerminals {
|
||||
/** optional structured query to filter servers. */
|
||||
/** Optional structured query to filter servers. */
|
||||
query?: ServerQuery;
|
||||
}
|
||||
|
||||
@@ -4655,7 +4655,7 @@ export interface CommitSync {
|
||||
export enum TerminalRecreateMode {
|
||||
/**
|
||||
* Never kill the old terminal if it already exists.
|
||||
* If the command is different, returns error.
|
||||
* If the init command is different, returns error.
|
||||
*/
|
||||
Never = "Never",
|
||||
/** Always kill the old terminal and create new one */
|
||||
@@ -4664,109 +4664,50 @@ export enum TerminalRecreateMode {
|
||||
DifferentCommand = "DifferentCommand",
|
||||
}
|
||||
|
||||
/** Query to connect to a container attach session (interactive shell over websocket) on the given server. */
|
||||
export interface ConnectContainerAttachQuery {
|
||||
/** Server Id or name */
|
||||
server: string;
|
||||
/** The container name */
|
||||
container: string;
|
||||
/**
|
||||
* Specify the recreate behavior.
|
||||
* Default is 'DifferentCommand'
|
||||
*/
|
||||
recreate?: TerminalRecreateMode;
|
||||
/** Specify the container terminal mode (exec or attach) */
|
||||
export enum ContainerTerminalMode {
|
||||
Exec = "exec",
|
||||
Attach = "attach",
|
||||
}
|
||||
|
||||
/** Query to connect to a container exec session (interactive shell over websocket) on the given server. */
|
||||
export interface ConnectContainerExecQuery {
|
||||
/** Server Id or name */
|
||||
server: string;
|
||||
/** The container name */
|
||||
container: string;
|
||||
/** The shell to use (eg. `sh` or `bash`) */
|
||||
shell: string;
|
||||
/** Args to init the Terminal if needed. */
|
||||
export interface InitTerminal {
|
||||
/**
|
||||
* Specify the recreate behavior.
|
||||
* Default is 'DifferentCommand'
|
||||
* The shell command (eg `bash`) to init the shell.
|
||||
*
|
||||
* Default:
|
||||
* - Server: Configured on each Periphery
|
||||
* - Container: `sh`
|
||||
*/
|
||||
command?: string;
|
||||
/** Default: `Never` */
|
||||
recreate?: TerminalRecreateMode;
|
||||
/**
|
||||
* Only relevant for container-type terminals.
|
||||
* Specify the container terminal mode (`exec` or `attach`).
|
||||
* Default: `exec`
|
||||
*/
|
||||
mode?: ContainerTerminalMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to connect to a container attach session (interactive shell over websocket) on the given Deployment.
|
||||
* This call will use access to the Deployment Terminal to permission the call.
|
||||
*/
|
||||
export interface ConnectDeploymentAttachQuery {
|
||||
/** Deployment Id or name */
|
||||
deployment: string;
|
||||
/**
|
||||
* Specify the recreate behavior.
|
||||
* Default is 'DifferentCommand'
|
||||
*/
|
||||
recreate?: TerminalRecreateMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to connect to a container exec session (interactive shell over websocket) on the given Deployment.
|
||||
* This call will use access to the Deployment Terminal to permission the call.
|
||||
*/
|
||||
export interface ConnectDeploymentExecQuery {
|
||||
/** Deployment Id or name */
|
||||
deployment: string;
|
||||
/** The shell to use (eg. `sh` or `bash`) */
|
||||
shell: string;
|
||||
/**
|
||||
* Specify the recreate behavior.
|
||||
* Default is 'DifferentCommand'
|
||||
*/
|
||||
recreate?: TerminalRecreateMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to connect to a container attach session (interactive shell over websocket) on the given Stack / service.
|
||||
* This call will use access to the Stack Terminal to permission the call.
|
||||
*/
|
||||
export interface ConnectStackAttachQuery {
|
||||
/** Stack Id or name */
|
||||
stack: string;
|
||||
/** The service name to attach to */
|
||||
service: string;
|
||||
/**
|
||||
* Specify the recreate behavior.
|
||||
* Default is 'DifferentCommand'
|
||||
*/
|
||||
recreate?: TerminalRecreateMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to connect to a container exec session (interactive shell over websocket) on the given Stack / service.
|
||||
* This call will use access to the Stack Terminal to permission the call.
|
||||
*/
|
||||
export interface ConnectStackExecQuery {
|
||||
/** Stack Id or name */
|
||||
stack: string;
|
||||
/** The service name to connect to */
|
||||
service: string;
|
||||
/** The shell to use (eg. `sh` or `bash`) */
|
||||
shell: string;
|
||||
/**
|
||||
* Specify the recreate behavior.
|
||||
* Default is 'DifferentCommand'
|
||||
*/
|
||||
recreate?: TerminalRecreateMode;
|
||||
}
|
||||
|
||||
/** Query to connect to a terminal (interactive shell over websocket) on the given server. */
|
||||
/** Connect to a Terminal. */
|
||||
export interface ConnectTerminalQuery {
|
||||
/** Server Id or name */
|
||||
server: string;
|
||||
/** The target to create terminal for. */
|
||||
target: TerminalTarget;
|
||||
/**
|
||||
* Each periphery can keep multiple terminals open.
|
||||
* If a terminals with the specified name does not exist,
|
||||
* the call will fail.
|
||||
* Create a terminal using [CreateTerminal][super::write::server::CreateTerminal]
|
||||
* Terminal name to connect to.
|
||||
* If it may not exist yet, also pass 'init' params
|
||||
* to include initialization.
|
||||
* Default: Depends on target.
|
||||
*/
|
||||
terminal: string;
|
||||
terminal?: string;
|
||||
/**
|
||||
* Pass to init the terminal session
|
||||
* for when the terminal doesn't already exist.
|
||||
*
|
||||
* Example: ?...(query)&init[command]=bash&init[recreate]=DifferentCommand
|
||||
*/
|
||||
init?: InitTerminal;
|
||||
}
|
||||
|
||||
/** Blkio stats entry. This type is Linux-specific and omitted for Windows containers. */
|
||||
@@ -5330,23 +5271,32 @@ export interface CreateTag {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a terminal on the server.
|
||||
* Create a Terminal.
|
||||
* Requires minimum Read + Terminal permission on the target Resource.
|
||||
* Response: [NoData]
|
||||
*/
|
||||
export interface CreateTerminal {
|
||||
/** Server Id or name */
|
||||
server: string;
|
||||
/** The name of the terminal on the server to create. */
|
||||
/** A name for the Terminal session. */
|
||||
name: string;
|
||||
/** The target to create terminal for */
|
||||
target: TerminalTarget;
|
||||
/**
|
||||
* The shell command (eg `bash`) to init the shell.
|
||||
*
|
||||
* This can also include args:
|
||||
* `docker exec -it container sh`
|
||||
*
|
||||
* Default: Configured on each Periphery
|
||||
* Default:
|
||||
* - Server: Configured on each Periphery
|
||||
* - ContainerExec: `sh`
|
||||
* - Attach: unused
|
||||
*/
|
||||
command?: string;
|
||||
/**
|
||||
* For container terminals, choose 'exec' or 'attach'.
|
||||
*
|
||||
* Default
|
||||
* - Server: ignored
|
||||
* - Container / Stack / Deployment: `exec`
|
||||
*/
|
||||
mode?: ContainerTerminalMode;
|
||||
/** Default: `Never` */
|
||||
recreate?: TerminalRecreateMode;
|
||||
}
|
||||
@@ -5394,7 +5344,7 @@ export interface DeleteAlerter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all terminals on the server.
|
||||
* Delete all Terminals on the Server.
|
||||
* Response: [NoData]
|
||||
*/
|
||||
export interface DeleteAllTerminals {
|
||||
@@ -5553,13 +5503,13 @@ export interface DeleteTag {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a terminal on the server.
|
||||
* Delete a terminal.
|
||||
* Response: [NoData]
|
||||
*/
|
||||
export interface DeleteTerminal {
|
||||
/** Server Id or name */
|
||||
server: string;
|
||||
/** The name of the terminal on the server to delete. */
|
||||
/** Server / Container / Stack / Deployment */
|
||||
target: TerminalTarget;
|
||||
/** The name of the Terminal to delete. */
|
||||
terminal: string;
|
||||
}
|
||||
|
||||
@@ -5721,76 +5671,17 @@ export interface ExchangeForJwt {
|
||||
token: string;
|
||||
}
|
||||
|
||||
/** Execute a command in the given containers shell. */
|
||||
export interface ExecuteContainerExecBody {
|
||||
/** Server Id or name */
|
||||
server: string;
|
||||
/** The container name */
|
||||
container: string;
|
||||
/** The shell to use (eg. `sh` or `bash`) */
|
||||
shell: string;
|
||||
/** The command to execute. */
|
||||
command: string;
|
||||
/**
|
||||
* Specify the recreate behavior.
|
||||
* Default is 'DifferentCommand'
|
||||
*/
|
||||
recreate?: TerminalRecreateMode;
|
||||
}
|
||||
|
||||
/** Execute a command in the given containers shell. */
|
||||
export interface ExecuteDeploymentExecBody {
|
||||
/** Deployment Id or name */
|
||||
deployment: string;
|
||||
/** The shell to use (eg. `sh` or `bash`) */
|
||||
shell: string;
|
||||
/** The command to execute. */
|
||||
command: string;
|
||||
/**
|
||||
* Specify the recreate behavior.
|
||||
* Default is 'DifferentCommand'
|
||||
*/
|
||||
recreate?: TerminalRecreateMode;
|
||||
}
|
||||
|
||||
/** Execute a command in the given containers shell. */
|
||||
export interface ExecuteStackExecBody {
|
||||
/** Stack Id or name */
|
||||
stack: string;
|
||||
/** The service name to connect to */
|
||||
service: string;
|
||||
/** The shell to use (eg. `sh` or `bash`) */
|
||||
shell: string;
|
||||
/** The command to execute. */
|
||||
command: string;
|
||||
/**
|
||||
* Specify the recreate behavior.
|
||||
* Default is 'DifferentCommand'
|
||||
*/
|
||||
recreate?: TerminalRecreateMode;
|
||||
}
|
||||
|
||||
/** Init a terminal on the server. */
|
||||
export interface InitTerminal {
|
||||
/**
|
||||
* The shell command (eg `bash`) to init the shell.
|
||||
*
|
||||
* This can also include args:
|
||||
* `docker exec -it container sh`
|
||||
*
|
||||
* Default: Configured on each Periphery
|
||||
*/
|
||||
command?: string;
|
||||
/** Default: `Never` */
|
||||
recreate?: TerminalRecreateMode;
|
||||
}
|
||||
|
||||
/** Execute a terminal command on the given server. */
|
||||
export interface ExecuteTerminalBody {
|
||||
/** Server Id or name */
|
||||
server: string;
|
||||
/** The name of the terminal on the server to use to execute. */
|
||||
terminal: string;
|
||||
/** The target to create terminal for. */
|
||||
target: TerminalTarget;
|
||||
/**
|
||||
* Terminal name to connect to.
|
||||
* If it may not exist yet, also pass 'init' params
|
||||
* to include initialization.
|
||||
* Default: Depends on target.
|
||||
*/
|
||||
terminal?: string;
|
||||
/** The command to execute. */
|
||||
command: string;
|
||||
/**
|
||||
@@ -6747,20 +6638,8 @@ export interface ListAlertsResponse {
|
||||
export interface ListAllDockerContainers {
|
||||
/** Filter by server id or name. */
|
||||
servers?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* List the current terminals on specified server.
|
||||
* Response: [ListAllTerminalsResponse].
|
||||
*/
|
||||
export interface ListAllTerminals {
|
||||
/** optional structured query to filter servers. */
|
||||
query?: ServerQuery;
|
||||
/**
|
||||
* Force a fresh call to Periphery for the list.
|
||||
* Otherwise the response will be cached for 30s
|
||||
*/
|
||||
fresh?: boolean;
|
||||
/** Filter by container name. */
|
||||
containers?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7119,17 +6998,14 @@ export interface ListTags {
|
||||
}
|
||||
|
||||
/**
|
||||
* List the current terminals on specified server.
|
||||
* List Terminals.
|
||||
* Response: [ListTerminalsResponse].
|
||||
*/
|
||||
export interface ListTerminals {
|
||||
/** Id or name */
|
||||
server: string;
|
||||
/**
|
||||
* Force a fresh call to Periphery for the list.
|
||||
* Otherwise the response will be cached for 30s
|
||||
*/
|
||||
fresh?: boolean;
|
||||
/** Filter the Terminals returned by the Target. */
|
||||
target?: TerminalTarget;
|
||||
/** Return results with resource names instead of ids. */
|
||||
use_names?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7643,6 +7519,12 @@ export interface RepoExecutionResponse {
|
||||
commit_message?: string;
|
||||
}
|
||||
|
||||
/** JSON structure to send new terminal window dimensions */
|
||||
export interface ResizeDimensions {
|
||||
rows: number;
|
||||
cols: number;
|
||||
}
|
||||
|
||||
export interface ResourceToml<PartialConfig> {
|
||||
/** The resource name. Required */
|
||||
name: string;
|
||||
@@ -8634,11 +8516,6 @@ export type AuthRequest =
|
||||
| { type: "ExchangeForJwt", params: ExchangeForJwt }
|
||||
| { type: "GetUser", params: GetUser };
|
||||
|
||||
export enum ContainerTerminalMode {
|
||||
Exec = "exec",
|
||||
Attach = "attach",
|
||||
}
|
||||
|
||||
/** Days of the week */
|
||||
export enum DayOfWeek {
|
||||
Monday = "Monday",
|
||||
@@ -8841,7 +8718,6 @@ export type ReadRequest =
|
||||
| { type: "ListServers", params: ListServers }
|
||||
| { type: "ListFullServers", params: ListFullServers }
|
||||
| { type: "ListTerminals", params: ListTerminals }
|
||||
| { type: "ListAllTerminals", params: ListAllTerminals }
|
||||
| { type: "GetDockerContainersSummary", params: GetDockerContainersSummary }
|
||||
| { type: "ListAllDockerContainers", params: ListAllDockerContainers }
|
||||
| { type: "ListDockerContainers", params: ListDockerContainers }
|
||||
@@ -9012,10 +8888,6 @@ export type WriteRequest =
|
||||
| { type: "UpdateServer", params: UpdateServer }
|
||||
| { type: "RenameServer", params: RenameServer }
|
||||
| { type: "CreateNetwork", params: CreateNetwork }
|
||||
| { type: "CreateTerminal", params: CreateTerminal }
|
||||
| { type: "DeleteTerminal", params: DeleteTerminal }
|
||||
| { type: "DeleteAllTerminals", params: DeleteAllTerminals }
|
||||
| { type: "BatchDeleteAllTerminals", params: BatchDeleteAllTerminals }
|
||||
| { type: "UpdateServerPublicKey", params: UpdateServerPublicKey }
|
||||
| { type: "RotateServerKeys", params: RotateServerKeys }
|
||||
| { type: "CreateStack", params: CreateStack }
|
||||
@@ -9072,6 +8944,10 @@ export type WriteRequest =
|
||||
| { type: "WriteSyncFileContents", params: WriteSyncFileContents }
|
||||
| { type: "CommitSync", params: CommitSync }
|
||||
| { type: "RefreshResourceSyncPending", params: RefreshResourceSyncPending }
|
||||
| { type: "CreateTerminal", params: CreateTerminal }
|
||||
| { type: "DeleteTerminal", params: DeleteTerminal }
|
||||
| { type: "DeleteAllTerminals", params: DeleteAllTerminals }
|
||||
| { type: "BatchDeleteAllTerminals", params: BatchDeleteAllTerminals }
|
||||
| { type: "CreateTag", params: CreateTag }
|
||||
| { type: "DeleteTag", params: DeleteTag }
|
||||
| { type: "RenameTag", params: RenameTag }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use komodo_client::{
|
||||
api::write::TerminalRecreateMode,
|
||||
entities::{NoData, server::TerminalInfo},
|
||||
use komodo_client::entities::{
|
||||
NoData,
|
||||
terminal::{Terminal, TerminalRecreateMode, TerminalTarget},
|
||||
};
|
||||
use resolver_api::Resolve;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -11,19 +11,18 @@ pub const START_OF_OUTPUT: &str = "__KOMODO_START_OF_OUTPUT__";
|
||||
pub const END_OF_OUTPUT: &str = "__KOMODO_END_OF_OUTPUT__";
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Resolve)]
|
||||
#[response(Vec<TerminalInfo>)]
|
||||
#[response(Vec<Terminal>)]
|
||||
#[error(anyhow::Error)]
|
||||
pub struct ListTerminals {
|
||||
/// If none, only includes non-container terminals.
|
||||
/// if Some, only includes that containers terminals.
|
||||
pub container: Option<String>,
|
||||
/// Optionally restrict list to specific target.
|
||||
pub target: Option<TerminalTarget>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Resolve)]
|
||||
#[response(NoData)]
|
||||
#[error(anyhow::Error)]
|
||||
pub struct CreateTerminal {
|
||||
/// The name of the terminal to create
|
||||
pub struct CreateServerTerminal {
|
||||
/// A name for the terminal session
|
||||
pub name: String,
|
||||
/// The shell command (eg `bash`) to init the shell.
|
||||
///
|
||||
@@ -32,6 +31,46 @@ pub struct CreateTerminal {
|
||||
///
|
||||
/// Default: Set in Periphery config.
|
||||
pub command: Option<String>,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default: `Never`
|
||||
#[serde(default)]
|
||||
pub recreate: TerminalRecreateMode,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Resolve)]
|
||||
#[response(NoData)]
|
||||
#[error(anyhow::Error)]
|
||||
pub struct CreateContainerExecTerminal {
|
||||
/// A name for the terminal session
|
||||
pub name: String,
|
||||
/// The target for the terminal sessions (Container, Stack, Deployment).
|
||||
pub target: TerminalTarget,
|
||||
/// The name of the container to connect to
|
||||
pub container: String,
|
||||
/// The command to init shell inside container.
|
||||
/// Default: `sh`
|
||||
pub command: Option<String>,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default: `Never`
|
||||
#[serde(default)]
|
||||
pub recreate: TerminalRecreateMode,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Resolve)]
|
||||
#[response(NoData)]
|
||||
#[error(anyhow::Error)]
|
||||
pub struct CreateContainerAttachTerminal {
|
||||
/// A name for the terminal session
|
||||
pub name: String,
|
||||
/// The target for the terminal sessions (Container, Stack, Deployment).
|
||||
pub target: TerminalTarget,
|
||||
/// The name of the container to attach to
|
||||
pub container: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default: `Never`
|
||||
#[serde(default)]
|
||||
pub recreate: TerminalRecreateMode,
|
||||
@@ -45,38 +84,8 @@ pub struct CreateTerminal {
|
||||
pub struct ConnectTerminal {
|
||||
/// The name of the terminal to connect to
|
||||
pub terminal: String,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Resolve)]
|
||||
#[response(Uuid)]
|
||||
#[error(anyhow::Error)]
|
||||
pub struct ConnectContainerExec {
|
||||
/// The name of the container to connect to.
|
||||
pub container: String,
|
||||
/// The shell to start inside container.
|
||||
/// Default: `sh`
|
||||
#[serde(default = "default_container_shell")]
|
||||
pub shell: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
#[serde(default = "default_container_recreate_mode")]
|
||||
pub recreate: TerminalRecreateMode,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Resolve)]
|
||||
#[response(Uuid)]
|
||||
#[error(anyhow::Error)]
|
||||
pub struct ConnectContainerAttach {
|
||||
/// The name of the container to attach to.
|
||||
pub container: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
#[serde(default = "default_container_recreate_mode")]
|
||||
pub recreate: TerminalRecreateMode,
|
||||
/// The target for the terminal session
|
||||
pub target: TerminalTarget,
|
||||
}
|
||||
|
||||
//
|
||||
@@ -96,8 +105,10 @@ pub struct DisconnectTerminal {
|
||||
#[response(NoData)]
|
||||
#[error(anyhow::Error)]
|
||||
pub struct DeleteTerminal {
|
||||
/// The name of the terminal to delete
|
||||
/// The name of the terminal to delete.
|
||||
pub terminal: String,
|
||||
/// The terminal target.
|
||||
pub target: TerminalTarget,
|
||||
}
|
||||
|
||||
//
|
||||
@@ -116,34 +127,8 @@ pub struct DeleteAllTerminals {}
|
||||
pub struct ExecuteTerminal {
|
||||
/// Specify the terminal to execute the command on.
|
||||
pub terminal: String,
|
||||
/// The terminal target.
|
||||
pub target: TerminalTarget,
|
||||
/// The command to execute.
|
||||
pub command: String,
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Resolve)]
|
||||
#[response(Uuid)]
|
||||
#[error(anyhow::Error)]
|
||||
pub struct ExecuteContainerExec {
|
||||
/// The name of the container to execute command in.
|
||||
pub container: String,
|
||||
/// The shell to start inside container.
|
||||
/// Default: `sh`
|
||||
#[serde(default = "default_container_shell")]
|
||||
pub shell: String,
|
||||
/// The command to execute.
|
||||
pub command: String,
|
||||
/// Specify the recreate behavior.
|
||||
/// Default is 'DifferentCommand'
|
||||
#[serde(default = "default_container_recreate_mode")]
|
||||
pub recreate: TerminalRecreateMode,
|
||||
}
|
||||
|
||||
fn default_container_shell() -> String {
|
||||
String::from("sh")
|
||||
}
|
||||
|
||||
fn default_container_recreate_mode() -> TerminalRecreateMode {
|
||||
TerminalRecreateMode::DifferentCommand
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user