Skip to content

Commit

Permalink
Merge pull request #2156 from fermyon/sockets
Browse files Browse the repository at this point in the history
Basic Socket Support
  • Loading branch information
rylev authored Dec 14, 2023
2 parents 7b8af17 + 6753c16 commit d41deb9
Show file tree
Hide file tree
Showing 28 changed files with 1,182 additions and 22 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions crates/core/src/store.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::{anyhow, Result};
use bytes::Bytes;
use cap_std::ipnet::IpNet;
use std::{
io::{Read, Write},
path::{Path, PathBuf},
Expand Down Expand Up @@ -175,6 +176,36 @@ impl StoreBuilder {
});
}

/// Insert IP network with a given port range
pub fn insert_ip_net_port_range(
&mut self,
ip_net: IpNet,
ports_start: u16,
ports_end: Option<u16>,
) {
self.with_wasi(|wasi| match wasi {
WasiCtxBuilder::Preview1(_) => {
panic!("Enabling network only allowed in preview2")
}
WasiCtxBuilder::Preview2(ctx) => {
ctx.insert_ip_net_port_range(ip_net, ports_start, ports_end);
}
});
}

/// Inherit the host network with a few hardcoded caveats
pub fn inherit_limited_network(&mut self) {
self.with_wasi(|wasi| match wasi {
WasiCtxBuilder::Preview1(_) => {
panic!("Enabling network only allowed in preview2")
}
WasiCtxBuilder::Preview2(ctx) => {
// TODO: ctx.allow_udp(false);
ctx.inherit_network(cap_std::ambient_authority());
}
});
}

/// Sets the WASI `stdin` descriptor to the given [`Read`]er.
pub fn stdin_pipe(
&mut self,
Expand Down
24 changes: 20 additions & 4 deletions crates/outbound-networking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ impl AllowedHostConfig {
})
}

pub fn scheme(&self) -> &SchemeConfig {
&self.scheme
}

pub fn host(&self) -> &HostConfig {
&self.host
}

pub fn port(&self) -> &PortConfig {
&self.port
}

fn allows(&self, url: &OutboundUrl) -> bool {
self.scheme.allows(&url.scheme)
&& self.host.allows(&url.host)
Expand All @@ -96,7 +108,7 @@ impl std::fmt::Display for AllowedHostConfig {
}

#[derive(PartialEq, Eq, Debug, Clone)]
enum SchemeConfig {
pub enum SchemeConfig {
Any,
List(Vec<String>),
}
Expand All @@ -119,6 +131,10 @@ impl SchemeConfig {
Ok(Self::List(vec![scheme.into()]))
}

pub fn allows_any(&self) -> bool {
matches!(self, Self::Any)
}

fn allows(&self, scheme: &str) -> bool {
match self {
SchemeConfig::Any => true,
Expand All @@ -128,7 +144,7 @@ impl SchemeConfig {
}

#[derive(Debug, PartialEq, Eq, Clone)]
enum HostConfig {
pub enum HostConfig {
Any,
ToSelf,
List(Vec<String>),
Expand Down Expand Up @@ -166,7 +182,7 @@ impl HostConfig {
}

#[derive(Debug, PartialEq, Eq, Clone)]
enum PortConfig {
pub enum PortConfig {
Any,
List(Vec<IndividualPortConfig>),
}
Expand Down Expand Up @@ -207,7 +223,7 @@ impl PortConfig {
}

#[derive(Debug, PartialEq, Eq, Clone)]
enum IndividualPortConfig {
pub enum IndividualPortConfig {
Port(u16),
Range(Range<u16>),
}
Expand Down
1 change: 1 addition & 0 deletions crates/trigger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ spin-key-value = { path = "../key-value" }
spin-key-value-azure = { path = "../key-value-azure" }
spin-key-value-redis = { path = "../key-value-redis" }
spin-key-value-sqlite = { path = "../key-value-sqlite" }
spin-outbound-networking = { path = "../outbound-networking" }
spin-sqlite = { path = "../sqlite" }
spin-sqlite-inproc = { path = "../sqlite-inproc" }
spin-sqlite-libsql = { path = "../sqlite-libsql" }
Expand Down
2 changes: 2 additions & 0 deletions crates/trigger/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use serde::de::DeserializeOwned;
use spin_app::Loader;
use spin_common::{arg_parser::parse_kv, sloth};

use crate::network::Network;
use crate::runtime_config::llm::LLmOptions;
use crate::runtime_config::sqlite::SqlitePersistenceMessageHook;
use crate::stdio::StdioLoggingTriggerHooks;
Expand Down Expand Up @@ -192,6 +193,7 @@ where
self.update_config(builder.config_mut())?;

builder.hooks(StdioLoggingTriggerHooks::new(self.follow_components()));
builder.hooks(Network);
builder.hooks(KeyValuePersistenceMessageHook);
builder.hooks(SqlitePersistenceMessageHook);

Expand Down
1 change: 1 addition & 0 deletions crates/trigger/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod cli;
pub mod loader;
mod network;
mod runtime_config;
mod stdio;

Expand Down
62 changes: 62 additions & 0 deletions crates/trigger/src/network.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use crate::TriggerHooks;

pub struct Network;

impl TriggerHooks for Network {
fn component_store_builder(
&self,
component: &spin_app::AppComponent,
store_builder: &mut spin_core::StoreBuilder,
) -> anyhow::Result<()> {
let hosts = component
.get_metadata(spin_outbound_networking::ALLOWED_HOSTS_KEY)?
.unwrap_or_default();
let allowed_hosts = spin_outbound_networking::AllowedHostsConfig::parse(&hosts)?;
match allowed_hosts {
spin_outbound_networking::AllowedHostsConfig::All => {
store_builder.inherit_limited_network()
}
spin_outbound_networking::AllowedHostsConfig::SpecificHosts(configs) => {
for config in configs {
if config.scheme().allows_any() {
match config.host() {
spin_outbound_networking::HostConfig::Any => {
store_builder.inherit_limited_network()
}
spin_outbound_networking::HostConfig::ToSelf => {}
spin_outbound_networking::HostConfig::List(hosts) => {
for host in hosts {
let Ok(ip_net) =
// Parse the host as an `IpNet` cidr block and if it fails
// then try parsing again with `/32` appended to the end.
host.parse().or_else(|_| format!("{host}/32").parse())
else {
continue;
};
match config.port() {
spin_outbound_networking::PortConfig::Any => {
store_builder.insert_ip_net_port_range(ip_net, 0, None);
}
spin_outbound_networking::PortConfig::List(ports) => {
for port in ports {
match port {
spin_outbound_networking::IndividualPortConfig::Port(p) => {
store_builder.insert_ip_net_port_range(ip_net, *p, p.checked_add(1));
}
spin_outbound_networking::IndividualPortConfig::Range(r) => {
store_builder.insert_ip_net_port_range(ip_net, r.start, Some(r.end))
}
}
}
}
}
}
}
}
}
}
}
}
Ok(())
}
}
2 changes: 1 addition & 1 deletion e2e-tests.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ARG FETCH_SPIN=true
ARG SPIN_VERSION=canary

WORKDIR /root
RUN apt-get update && apt-get install -y wget sudo xz-utils gcc git pkg-config redis clang libicu-dev docker.io
RUN apt-get update && apt-get install -y wget sudo xz-utils gcc git pkg-config redis clang libicu-dev docker.io netcat

# nodejs
RUN curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
Expand Down
1 change: 1 addition & 0 deletions examples/spin-timer/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit d41deb9

Please sign in to comment.