mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-30 04:34:27 +00:00
feat(shim-mgmt): iptables handler
Support the handlers in runtime, which are used by kata-ctl iptables series of commands in runtime. Fixes: #5370 Signed-off-by: Ji-Xinyou <jerryji0414@outlook.com>
This commit is contained in:
parent
288e337a6f
commit
f8f97c1e22
@ -113,5 +113,7 @@ impl_agent!(
|
||||
create_sandbox | crate::CreateSandboxRequest | crate::Empty | None,
|
||||
destroy_sandbox | crate::Empty | crate::Empty | None,
|
||||
copy_file | crate::CopyFileRequest | crate::Empty | None,
|
||||
get_oom_event | crate::Empty | crate::OomEventResponse | Some(0)
|
||||
get_oom_event | crate::Empty | crate::OomEventResponse | Some(0),
|
||||
get_ip_tables | crate::GetIPTablesRequest | crate::GetIPTablesResponse | None,
|
||||
set_ip_tables | crate::SetIPTablesRequest | crate::SetIPTablesResponse | None
|
||||
);
|
||||
|
@ -16,14 +16,15 @@ use crate::{
|
||||
ARPNeighbor, ARPNeighbors, AddArpNeighborRequest, AgentDetails, BlkioStats,
|
||||
BlkioStatsEntry, CgroupStats, CheckRequest, CloseStdinRequest, ContainerID,
|
||||
CopyFileRequest, CpuStats, CpuUsage, CreateContainerRequest, CreateSandboxRequest, Device,
|
||||
Empty, ExecProcessRequest, FSGroup, FSGroupChangePolicy, GuestDetailsResponse,
|
||||
HealthCheckResponse, HugetlbStats, IPAddress, IPFamily, Interface, Interfaces,
|
||||
KernelModule, MemHotplugByProbeRequest, MemoryData, MemoryStats, NetworkStats,
|
||||
OnlineCPUMemRequest, PidsStats, ReadStreamRequest, ReadStreamResponse,
|
||||
RemoveContainerRequest, ReseedRandomDevRequest, Route, Routes, SetGuestDateTimeRequest,
|
||||
SignalProcessRequest, StatsContainerResponse, Storage, StringUser, ThrottlingData,
|
||||
TtyWinResizeRequest, UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest,
|
||||
VersionCheckResponse, WaitProcessRequest, WriteStreamRequest,
|
||||
Empty, ExecProcessRequest, FSGroup, FSGroupChangePolicy, GetIPTablesRequest,
|
||||
GetIPTablesResponse, GuestDetailsResponse, HealthCheckResponse, HugetlbStats, IPAddress,
|
||||
IPFamily, Interface, Interfaces, KernelModule, MemHotplugByProbeRequest, MemoryData,
|
||||
MemoryStats, NetworkStats, OnlineCPUMemRequest, PidsStats, ReadStreamRequest,
|
||||
ReadStreamResponse, RemoveContainerRequest, ReseedRandomDevRequest, Route, Routes,
|
||||
SetGuestDateTimeRequest, SetIPTablesRequest, SetIPTablesResponse, SignalProcessRequest,
|
||||
StatsContainerResponse, Storage, StringUser, ThrottlingData, TtyWinResizeRequest,
|
||||
UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest, VersionCheckResponse,
|
||||
WaitProcessRequest, WriteStreamRequest,
|
||||
},
|
||||
OomEventResponse, WaitProcessResponse, WriteStreamResponse,
|
||||
};
|
||||
@ -388,6 +389,41 @@ impl From<agent::WriteStreamResponse> for WriteStreamResponse {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GetIPTablesRequest> for agent::GetIPTablesRequest {
|
||||
fn from(from: GetIPTablesRequest) -> Self {
|
||||
Self {
|
||||
is_ipv6: from.is_ipv6,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<agent::GetIPTablesResponse> for GetIPTablesResponse {
|
||||
fn from(from: agent::GetIPTablesResponse) -> Self {
|
||||
Self {
|
||||
data: from.get_data().to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SetIPTablesRequest> for agent::SetIPTablesRequest {
|
||||
fn from(from: SetIPTablesRequest) -> Self {
|
||||
Self {
|
||||
is_ipv6: from.is_ipv6,
|
||||
data: from.data,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<agent::SetIPTablesResponse> for SetIPTablesResponse {
|
||||
fn from(from: agent::SetIPTablesResponse) -> Self {
|
||||
Self {
|
||||
data: from.get_data().to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ExecProcessRequest> for agent::ExecProcessRequest {
|
||||
fn from(from: ExecProcessRequest) -> Self {
|
||||
Self {
|
||||
|
@ -16,11 +16,12 @@ pub mod types;
|
||||
pub use types::{
|
||||
ARPNeighbor, ARPNeighbors, AddArpNeighborRequest, BlkioStatsEntry, CheckRequest,
|
||||
CloseStdinRequest, ContainerID, ContainerProcessID, CopyFileRequest, CreateContainerRequest,
|
||||
CreateSandboxRequest, Empty, ExecProcessRequest, GetGuestDetailsRequest, GuestDetailsResponse,
|
||||
HealthCheckResponse, IPAddress, IPFamily, Interface, Interfaces, ListProcessesRequest,
|
||||
MemHotplugByProbeRequest, OnlineCPUMemRequest, OomEventResponse, ReadStreamRequest,
|
||||
ReadStreamResponse, RemoveContainerRequest, ReseedRandomDevRequest, Route, Routes,
|
||||
SetGuestDateTimeRequest, SignalProcessRequest, StatsContainerResponse, Storage,
|
||||
CreateSandboxRequest, Empty, ExecProcessRequest, GetGuestDetailsRequest, GetIPTablesRequest,
|
||||
GetIPTablesResponse, GuestDetailsResponse, HealthCheckResponse, IPAddress, IPFamily, Interface,
|
||||
Interfaces, ListProcessesRequest, MemHotplugByProbeRequest, OnlineCPUMemRequest,
|
||||
OomEventResponse, ReadStreamRequest, ReadStreamResponse, RemoveContainerRequest,
|
||||
ReseedRandomDevRequest, Route, Routes, SetGuestDateTimeRequest, SetIPTablesRequest,
|
||||
SetIPTablesResponse, SignalProcessRequest, StatsContainerResponse, Storage,
|
||||
TtyWinResizeRequest, UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest,
|
||||
VersionCheckResponse, WaitProcessRequest, WaitProcessResponse, WriteStreamRequest,
|
||||
WriteStreamResponse,
|
||||
@ -85,4 +86,6 @@ pub trait Agent: AgentManager + HealthService + Send + Sync {
|
||||
// utils
|
||||
async fn copy_file(&self, req: CopyFileRequest) -> Result<Empty>;
|
||||
async fn get_oom_event(&self, req: Empty) -> Result<OomEventResponse>;
|
||||
async fn get_ip_tables(&self, req: GetIPTablesRequest) -> Result<GetIPTablesResponse>;
|
||||
async fn set_ip_tables(&self, req: SetIPTablesRequest) -> Result<SetIPTablesResponse>;
|
||||
}
|
||||
|
@ -205,6 +205,27 @@ pub struct UpdateContainerRequest {
|
||||
pub mounts: Vec<oci::Mount>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug)]
|
||||
pub struct GetIPTablesRequest {
|
||||
pub is_ipv6: bool,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug)]
|
||||
pub struct GetIPTablesResponse {
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug)]
|
||||
pub struct SetIPTablesRequest {
|
||||
pub is_ipv6: bool,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug)]
|
||||
pub struct SetIPTablesResponse {
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default)]
|
||||
pub struct WriteStreamRequest {
|
||||
pub process_id: ContainerProcessID,
|
||||
|
@ -16,4 +16,8 @@ pub trait Sandbox: Send + Sync {
|
||||
|
||||
// agent function
|
||||
async fn agent_sock(&self) -> Result<String>;
|
||||
|
||||
// utils
|
||||
async fn set_iptables(&self, is_ipv6: bool, data: Vec<u8>) -> Result<Vec<u8>>;
|
||||
async fn get_iptables(&self, is_ipv6: bool) -> Result<Vec<u8>>;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use std::{path::Path, path::PathBuf, time::Duration};
|
||||
|
||||
use super::server::mgmt_socket_addr;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use hyper::{Body, Client, Response};
|
||||
use hyper::{Body, Client, Method, Request, Response};
|
||||
use hyperlocal::{UnixClientExt, UnixConnector, Uri};
|
||||
|
||||
/// Shim management client with timeout
|
||||
@ -58,4 +58,22 @@ impl MgmtClient {
|
||||
None => work.await.context("failed to GET"),
|
||||
}
|
||||
}
|
||||
|
||||
/// The http PUT method for client
|
||||
pub async fn put(&self, uri: &str, data: Vec<u8>) -> Result<Response<Body>> {
|
||||
let url: hyper::Uri = Uri::new(&self.sock_path, uri).into();
|
||||
let request = Request::builder()
|
||||
.method(Method::PUT)
|
||||
.uri(url)
|
||||
.body(Body::from(data))
|
||||
.unwrap();
|
||||
let work = self.client.request(request);
|
||||
match self.timeout {
|
||||
Some(timeout) => match tokio::time::timeout(timeout, work).await {
|
||||
Ok(result) => result.map_err(|e| anyhow!(e)),
|
||||
Err(_) => Err(anyhow!("TIMEOUT")),
|
||||
},
|
||||
None => work.await.context("failed to PUT"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,12 @@
|
||||
// This defines the handlers corresponding to the url when a request is sent to destined url,
|
||||
// the handler function should be invoked, and the corresponding data will be in the response
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use common::Sandbox;
|
||||
use hyper::{Body, Method, Request, Response, Result, StatusCode};
|
||||
use hyper::{Body, Method, Request, Response, StatusCode};
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::server::AGENT_URL;
|
||||
use super::server::{AGENT_URL, IP6_TABLE_URL, IP_TABLE_URL};
|
||||
|
||||
// main router for response, this works as a multiplexer on
|
||||
// http arrival which invokes the corresponding handler function
|
||||
@ -27,6 +28,12 @@ pub(crate) async fn handler_mux(
|
||||
);
|
||||
match (req.method(), req.uri().path()) {
|
||||
(&Method::GET, AGENT_URL) => agent_url_handler(sandbox, req).await,
|
||||
(&Method::PUT, IP_TABLE_URL) | (&Method::GET, IP_TABLE_URL) => {
|
||||
ip_table_handler(sandbox, req).await
|
||||
}
|
||||
(&Method::PUT, IP6_TABLE_URL) | (&Method::GET, IP6_TABLE_URL) => {
|
||||
ipv6_table_handler(sandbox, req).await
|
||||
}
|
||||
_ => Ok(not_found(req).await),
|
||||
}
|
||||
}
|
||||
@ -50,3 +57,49 @@ async fn agent_url_handler(
|
||||
.unwrap_or_else(|_| String::from(""));
|
||||
Ok(Response::new(Body::from(agent_sock)))
|
||||
}
|
||||
|
||||
/// the ipv4 handler of iptable operation
|
||||
async fn ip_table_handler(sandbox: Arc<dyn Sandbox>, req: Request<Body>) -> Result<Response<Body>> {
|
||||
generic_ip_table_handler(sandbox, req, false).await
|
||||
}
|
||||
|
||||
/// the ipv6 handler of iptable operation
|
||||
async fn ipv6_table_handler(
|
||||
sandbox: Arc<dyn Sandbox>,
|
||||
req: Request<Body>,
|
||||
) -> Result<Response<Body>> {
|
||||
generic_ip_table_handler(sandbox, req, true).await
|
||||
}
|
||||
|
||||
/// the generic iptable handler, for both ipv4 and ipv6
|
||||
/// this requires iptables-series binaries to be inside guest rootfs
|
||||
async fn generic_ip_table_handler(
|
||||
sandbox: Arc<dyn Sandbox>,
|
||||
req: Request<Body>,
|
||||
is_ipv6: bool,
|
||||
) -> Result<Response<Body>> {
|
||||
info!(sl!(), "handler: iptable ipv6?: {}", is_ipv6);
|
||||
match *req.method() {
|
||||
Method::GET => match sandbox.get_iptables(is_ipv6).await {
|
||||
Ok(data) => {
|
||||
let body = Body::from(data);
|
||||
Response::builder().body(body).map_err(|e| anyhow!(e))
|
||||
}
|
||||
_ => {
|
||||
Err(anyhow!("Failed to get iptable"))
|
||||
}
|
||||
},
|
||||
|
||||
Method::PUT => {
|
||||
let data = hyper::body::to_bytes(req.into_body()).await?;
|
||||
match sandbox.set_iptables(is_ipv6, data.to_vec()).await {
|
||||
Ok(resp_data) => Response::builder()
|
||||
.body(Body::from(resp_data))
|
||||
.map_err(|e| anyhow!(e)),
|
||||
_ => Err(anyhow!("Failed to set iptable")),
|
||||
}
|
||||
}
|
||||
|
||||
_ => Err(anyhow!("IP Tables only takes PUT and GET")),
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,9 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use agent::{self, kata::KataAgent, types::KernelModule, Agent};
|
||||
use agent::{
|
||||
self, kata::KataAgent, types::KernelModule, Agent, GetIPTablesRequest, SetIPTablesRequest,
|
||||
};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_trait::async_trait;
|
||||
use common::{
|
||||
@ -269,6 +271,28 @@ impl Sandbox for VirtSandbox {
|
||||
async fn agent_sock(&self) -> Result<String> {
|
||||
self.agent.agent_sock().await
|
||||
}
|
||||
|
||||
async fn set_iptables(&self, is_ipv6: bool, data: Vec<u8>) -> Result<Vec<u8>> {
|
||||
info!(sl!(), "sb: set_iptables invoked");
|
||||
let req = SetIPTablesRequest { is_ipv6, data };
|
||||
let resp = self
|
||||
.agent
|
||||
.set_ip_tables(req)
|
||||
.await
|
||||
.context("sandbox: failed to set iptables")?;
|
||||
Ok(resp.data)
|
||||
}
|
||||
|
||||
async fn get_iptables(&self, is_ipv6: bool) -> Result<Vec<u8>> {
|
||||
info!(sl!(), "sb: get_iptables invoked");
|
||||
let req = GetIPTablesRequest { is_ipv6 };
|
||||
let resp = self
|
||||
.agent
|
||||
.get_ip_tables(req)
|
||||
.await
|
||||
.context("sandbox: failed to get iptables")?;
|
||||
Ok(resp.data)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
Loading…
Reference in New Issue
Block a user