mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-05-01 05:04:26 +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,
|
create_sandbox | crate::CreateSandboxRequest | crate::Empty | None,
|
||||||
destroy_sandbox | crate::Empty | crate::Empty | None,
|
destroy_sandbox | crate::Empty | crate::Empty | None,
|
||||||
copy_file | crate::CopyFileRequest | 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,
|
ARPNeighbor, ARPNeighbors, AddArpNeighborRequest, AgentDetails, BlkioStats,
|
||||||
BlkioStatsEntry, CgroupStats, CheckRequest, CloseStdinRequest, ContainerID,
|
BlkioStatsEntry, CgroupStats, CheckRequest, CloseStdinRequest, ContainerID,
|
||||||
CopyFileRequest, CpuStats, CpuUsage, CreateContainerRequest, CreateSandboxRequest, Device,
|
CopyFileRequest, CpuStats, CpuUsage, CreateContainerRequest, CreateSandboxRequest, Device,
|
||||||
Empty, ExecProcessRequest, FSGroup, FSGroupChangePolicy, GuestDetailsResponse,
|
Empty, ExecProcessRequest, FSGroup, FSGroupChangePolicy, GetIPTablesRequest,
|
||||||
HealthCheckResponse, HugetlbStats, IPAddress, IPFamily, Interface, Interfaces,
|
GetIPTablesResponse, GuestDetailsResponse, HealthCheckResponse, HugetlbStats, IPAddress,
|
||||||
KernelModule, MemHotplugByProbeRequest, MemoryData, MemoryStats, NetworkStats,
|
IPFamily, Interface, Interfaces, KernelModule, MemHotplugByProbeRequest, MemoryData,
|
||||||
OnlineCPUMemRequest, PidsStats, ReadStreamRequest, ReadStreamResponse,
|
MemoryStats, NetworkStats, OnlineCPUMemRequest, PidsStats, ReadStreamRequest,
|
||||||
RemoveContainerRequest, ReseedRandomDevRequest, Route, Routes, SetGuestDateTimeRequest,
|
ReadStreamResponse, RemoveContainerRequest, ReseedRandomDevRequest, Route, Routes,
|
||||||
SignalProcessRequest, StatsContainerResponse, Storage, StringUser, ThrottlingData,
|
SetGuestDateTimeRequest, SetIPTablesRequest, SetIPTablesResponse, SignalProcessRequest,
|
||||||
TtyWinResizeRequest, UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest,
|
StatsContainerResponse, Storage, StringUser, ThrottlingData, TtyWinResizeRequest,
|
||||||
VersionCheckResponse, WaitProcessRequest, WriteStreamRequest,
|
UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest, VersionCheckResponse,
|
||||||
|
WaitProcessRequest, WriteStreamRequest,
|
||||||
},
|
},
|
||||||
OomEventResponse, WaitProcessResponse, WriteStreamResponse,
|
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 {
|
impl From<ExecProcessRequest> for agent::ExecProcessRequest {
|
||||||
fn from(from: ExecProcessRequest) -> Self {
|
fn from(from: ExecProcessRequest) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -16,11 +16,12 @@ pub mod types;
|
|||||||
pub use types::{
|
pub use types::{
|
||||||
ARPNeighbor, ARPNeighbors, AddArpNeighborRequest, BlkioStatsEntry, CheckRequest,
|
ARPNeighbor, ARPNeighbors, AddArpNeighborRequest, BlkioStatsEntry, CheckRequest,
|
||||||
CloseStdinRequest, ContainerID, ContainerProcessID, CopyFileRequest, CreateContainerRequest,
|
CloseStdinRequest, ContainerID, ContainerProcessID, CopyFileRequest, CreateContainerRequest,
|
||||||
CreateSandboxRequest, Empty, ExecProcessRequest, GetGuestDetailsRequest, GuestDetailsResponse,
|
CreateSandboxRequest, Empty, ExecProcessRequest, GetGuestDetailsRequest, GetIPTablesRequest,
|
||||||
HealthCheckResponse, IPAddress, IPFamily, Interface, Interfaces, ListProcessesRequest,
|
GetIPTablesResponse, GuestDetailsResponse, HealthCheckResponse, IPAddress, IPFamily, Interface,
|
||||||
MemHotplugByProbeRequest, OnlineCPUMemRequest, OomEventResponse, ReadStreamRequest,
|
Interfaces, ListProcessesRequest, MemHotplugByProbeRequest, OnlineCPUMemRequest,
|
||||||
ReadStreamResponse, RemoveContainerRequest, ReseedRandomDevRequest, Route, Routes,
|
OomEventResponse, ReadStreamRequest, ReadStreamResponse, RemoveContainerRequest,
|
||||||
SetGuestDateTimeRequest, SignalProcessRequest, StatsContainerResponse, Storage,
|
ReseedRandomDevRequest, Route, Routes, SetGuestDateTimeRequest, SetIPTablesRequest,
|
||||||
|
SetIPTablesResponse, SignalProcessRequest, StatsContainerResponse, Storage,
|
||||||
TtyWinResizeRequest, UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest,
|
TtyWinResizeRequest, UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest,
|
||||||
VersionCheckResponse, WaitProcessRequest, WaitProcessResponse, WriteStreamRequest,
|
VersionCheckResponse, WaitProcessRequest, WaitProcessResponse, WriteStreamRequest,
|
||||||
WriteStreamResponse,
|
WriteStreamResponse,
|
||||||
@ -85,4 +86,6 @@ pub trait Agent: AgentManager + HealthService + Send + Sync {
|
|||||||
// utils
|
// utils
|
||||||
async fn copy_file(&self, req: CopyFileRequest) -> Result<Empty>;
|
async fn copy_file(&self, req: CopyFileRequest) -> Result<Empty>;
|
||||||
async fn get_oom_event(&self, req: Empty) -> Result<OomEventResponse>;
|
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>,
|
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)]
|
#[derive(PartialEq, Clone, Default)]
|
||||||
pub struct WriteStreamRequest {
|
pub struct WriteStreamRequest {
|
||||||
pub process_id: ContainerProcessID,
|
pub process_id: ContainerProcessID,
|
||||||
|
@ -16,4 +16,8 @@ pub trait Sandbox: Send + Sync {
|
|||||||
|
|
||||||
// agent function
|
// agent function
|
||||||
async fn agent_sock(&self) -> Result<String>;
|
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 super::server::mgmt_socket_addr;
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use hyper::{Body, Client, Response};
|
use hyper::{Body, Client, Method, Request, Response};
|
||||||
use hyperlocal::{UnixClientExt, UnixConnector, Uri};
|
use hyperlocal::{UnixClientExt, UnixConnector, Uri};
|
||||||
|
|
||||||
/// Shim management client with timeout
|
/// Shim management client with timeout
|
||||||
@ -58,4 +58,22 @@ impl MgmtClient {
|
|||||||
None => work.await.context("failed to GET"),
|
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,
|
// 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
|
// the handler function should be invoked, and the corresponding data will be in the response
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
use common::Sandbox;
|
use common::Sandbox;
|
||||||
use hyper::{Body, Method, Request, Response, Result, StatusCode};
|
use hyper::{Body, Method, Request, Response, StatusCode};
|
||||||
use std::sync::Arc;
|
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
|
// main router for response, this works as a multiplexer on
|
||||||
// http arrival which invokes the corresponding handler function
|
// http arrival which invokes the corresponding handler function
|
||||||
@ -27,6 +28,12 @@ pub(crate) async fn handler_mux(
|
|||||||
);
|
);
|
||||||
match (req.method(), req.uri().path()) {
|
match (req.method(), req.uri().path()) {
|
||||||
(&Method::GET, AGENT_URL) => agent_url_handler(sandbox, req).await,
|
(&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),
|
_ => Ok(not_found(req).await),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,3 +57,49 @@ async fn agent_url_handler(
|
|||||||
.unwrap_or_else(|_| String::from(""));
|
.unwrap_or_else(|_| String::from(""));
|
||||||
Ok(Response::new(Body::from(agent_sock)))
|
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 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 anyhow::{anyhow, Context, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use common::{
|
use common::{
|
||||||
@ -269,6 +271,28 @@ impl Sandbox for VirtSandbox {
|
|||||||
async fn agent_sock(&self) -> Result<String> {
|
async fn agent_sock(&self) -> Result<String> {
|
||||||
self.agent.agent_sock().await
|
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]
|
#[async_trait]
|
||||||
|
Loading…
Reference in New Issue
Block a user