Skip to content

Commit 802fdaf

Browse files
authored
feat: add sandbox network out configuration (#1447)
1 parent 5e5f338 commit 802fdaf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1663
-436
lines changed

.golangci.yml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,16 @@ linters:
7272
forbid:
7373
- pattern: "^new$"
7474
msg: "Use &Type{} instead."
75-
# - pattern: os\.Getenv
76-
# msg: "Add your field to the configuration model instead."
75+
# - pattern: os\.Getenv
76+
# msg: "Add your field to the configuration model instead."
7777

7878
gocritic:
7979
disabled-checks:
8080
- appendAssign
8181
revive:
8282
enable-all-rules: true
8383
rules:
84-
- { disabled: true, name: add-constant } # todo: enable this
84+
- { disabled: true, name: add-constant } # todo: enable this
8585
- { disabled: true, name: argument-limit }
8686
- { disabled: true, name: bare-return }
8787
- { disabled: true, name: blank-imports }
@@ -96,7 +96,7 @@ linters:
9696
- { disabled: true, name: early-return }
9797
- { disabled: true, name: enforce-switch-style }
9898
- { disabled: true, name: exported }
99-
- { disabled: true, name: flag-parameter } # todo: enable this
99+
- { disabled: true, name: flag-parameter } # todo: enable this
100100
- { disabled: true, name: function-length }
101101
- { disabled: true, name: function-result-limit }
102102
- { disabled: true, name: get-return }
@@ -109,24 +109,24 @@ linters:
109109
- { disabled: true, name: package-comments }
110110
- { disabled: true, name: unchecked-type-assertion }
111111
- { disabled: true, name: unexported-naming }
112-
- { disabled: true, name: unhandled-error } # todo: enable this
113-
- { disabled: true, name: unnecessary-format } # todo: enable this
114-
- { disabled: true, name: unnecessary-stmt } # todo: enable this
112+
- { disabled: true, name: unhandled-error } # todo: enable this
113+
- { disabled: true, name: unnecessary-format } # todo: enable this
114+
- { disabled: true, name: unnecessary-stmt } # todo: enable this
115115
- { disabled: true, name: unused-receiver }
116-
- { disabled: true, name: use-errors-new } # todo: enable this
116+
- { disabled: true, name: use-errors-new } # todo: enable this
117117
- { disabled: true, name: var-declaration }
118118
- { disabled: true, name: var-naming }
119119

120120
staticcheck:
121121
checks:
122122
- all
123-
- -S1002 # Omit comparison with boolean constant
124-
- -SA1019 # TODO: Remove (Using a deprecated function, variable, constant or field)
125-
- -ST1000 # Incorrect or missing package comment
126-
- -ST1020 # The documentation of an exported function should start with the function’s name
127-
- -ST1021 # The documentation of an exported type should start with type’s name
128-
- -ST1003 # Poorly chosen identifier
129-
- -QF1008 # Omit embedded fields from selector expression
123+
- -S1002 # Omit comparison with boolean constant
124+
- -SA1019 # TODO: Remove (Using a deprecated function, variable, constant or field)
125+
- -ST1000 # Incorrect or missing package comment
126+
- -ST1020 # The documentation of an exported function should start with the function’s name
127+
- -ST1021 # The documentation of an exported type should start with type’s name
128+
- -ST1003 # Poorly chosen identifier
129+
- -QF1008 # Omit embedded fields from selector expression
130130

131131
run:
132132
go: 1.24.7

packages/api/internal/api/spec.gen.go

Lines changed: 115 additions & 112 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/api/internal/api/types.gen.go

Lines changed: 13 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/api/internal/handlers/sandbox.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ import (
1313
"go.uber.org/zap"
1414

1515
"github.com/e2b-dev/infra/packages/api/internal/api"
16-
"github.com/e2b-dev/infra/packages/api/internal/db/types"
16+
typesteam "github.com/e2b-dev/infra/packages/api/internal/db/types"
1717
"github.com/e2b-dev/infra/packages/db/queries"
18+
"github.com/e2b-dev/infra/packages/db/types"
1819
sbxlogger "github.com/e2b-dev/infra/packages/shared/pkg/logger/sandbox"
1920
"github.com/e2b-dev/infra/packages/shared/pkg/telemetry"
2021
)
@@ -28,7 +29,7 @@ func (a *APIStore) startSandbox(
2829
envVars map[string]string,
2930
metadata map[string]string,
3031
alias string,
31-
team *types.Team,
32+
team *typesteam.Team,
3233
build queries.EnvBuild,
3334
requestHeader *http.Header,
3435
isResume bool,
@@ -37,6 +38,7 @@ func (a *APIStore) startSandbox(
3738
autoPause bool,
3839
envdAccessToken *string,
3940
allowInternetAccess *bool,
41+
network *types.SandboxNetworkConfig,
4042
mcp api.Mcp,
4143
) (*api.Sandbox, *api.APIError) {
4244
startTime := time.Now()
@@ -62,6 +64,7 @@ func (a *APIStore) startSandbox(
6264
autoPause,
6365
envdAccessToken,
6466
allowInternetAccess,
67+
network,
6568
)
6669
if instanceErr != nil {
6770
telemetry.ReportError(ctx, "error when creating instance", instanceErr.Err)

packages/api/internal/handlers/sandbox_connect.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ func (a *APIStore) PostSandboxesSandboxIDConnect(c *gin.Context, sandboxID api.S
154154
autoPause,
155155
envdAccessToken,
156156
snap.AllowInternetAccess,
157-
nil,
157+
snap.Config.Network,
158+
nil, // mcp
158159
)
159160
if createErr != nil {
160161
zap.L().Error("Failed to resume sandbox", zap.Error(createErr.Err))

packages/api/internal/handlers/sandbox_create.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ import (
1313

1414
"github.com/e2b-dev/infra/packages/api/internal/api"
1515
"github.com/e2b-dev/infra/packages/api/internal/auth"
16-
"github.com/e2b-dev/infra/packages/api/internal/db/types"
16+
typesteam "github.com/e2b-dev/infra/packages/api/internal/db/types"
1717
"github.com/e2b-dev/infra/packages/api/internal/middleware/otel/metrics"
1818
"github.com/e2b-dev/infra/packages/api/internal/sandbox"
1919
"github.com/e2b-dev/infra/packages/api/internal/utils"
20+
"github.com/e2b-dev/infra/packages/db/types"
2021
"github.com/e2b-dev/infra/packages/shared/pkg/id"
2122
"github.com/e2b-dev/infra/packages/shared/pkg/logger"
2223
sbxlogger "github.com/e2b-dev/infra/packages/shared/pkg/logger/sandbox"
@@ -43,7 +44,7 @@ func (a *APIStore) PostSandboxes(c *gin.Context) {
4344
ctx := c.Request.Context()
4445

4546
// Get team from context, use TeamContextKey
46-
teamInfo := c.Value(auth.TeamContextKey).(*types.Team)
47+
teamInfo := c.Value(auth.TeamContextKey).(*typesteam.Team)
4748

4849
c.Set("teamID", teamInfo.Team.ID.String())
4950

@@ -157,6 +158,16 @@ func (a *APIStore) PostSandboxes(c *gin.Context) {
157158

158159
allowInternetAccess := body.AllowInternetAccess
159160

161+
var network *types.SandboxNetworkConfig
162+
if body.Network != nil {
163+
network = &types.SandboxNetworkConfig{
164+
Egress: &types.SandboxNetworkEgressConfig{
165+
AllowedAddresses: sharedUtils.DerefOrDefault(body.Network.AllowOut, nil),
166+
DeniedAddresses: sharedUtils.DerefOrDefault(body.Network.DenyOut, nil),
167+
},
168+
}
169+
}
170+
160171
sbx, createErr := a.startSandbox(
161172
ctx,
162173
sandboxID,
@@ -173,6 +184,7 @@ func (a *APIStore) PostSandboxes(c *gin.Context) {
173184
autoPause,
174185
envdAccessToken,
175186
allowInternetAccess,
187+
network,
176188
mcp,
177189
)
178190
if createErr != nil {

packages/api/internal/handlers/sandbox_resume.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ func (a *APIStore) PostSandboxesSandboxIDResume(c *gin.Context, sandboxID api.Sa
153153
autoPause,
154154
envdAccessToken,
155155
snap.AllowInternetAccess,
156-
nil,
156+
snap.Config.Network,
157+
nil, // mcp
157158
)
158159
if createErr != nil {
159160
zap.L().Error("Failed to resume sandbox", zap.Error(createErr.Err))

packages/api/internal/orchestrator/create_instance.go

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"net/http"
8+
"strings"
89
"time"
910

1011
"go.opentelemetry.io/otel/attribute"
@@ -13,25 +14,64 @@ import (
1314
"google.golang.org/protobuf/types/known/timestamppb"
1415

1516
"github.com/e2b-dev/infra/packages/api/internal/api"
16-
"github.com/e2b-dev/infra/packages/api/internal/db/types"
17+
teamtypes "github.com/e2b-dev/infra/packages/api/internal/db/types"
1718
"github.com/e2b-dev/infra/packages/api/internal/orchestrator/nodemanager"
1819
"github.com/e2b-dev/infra/packages/api/internal/orchestrator/placement"
1920
"github.com/e2b-dev/infra/packages/api/internal/sandbox"
2021
"github.com/e2b-dev/infra/packages/api/internal/utils"
2122
"github.com/e2b-dev/infra/packages/db/queries"
23+
"github.com/e2b-dev/infra/packages/db/types"
2224
"github.com/e2b-dev/infra/packages/shared/pkg/consts"
2325
"github.com/e2b-dev/infra/packages/shared/pkg/grpc/orchestrator"
2426
"github.com/e2b-dev/infra/packages/shared/pkg/logger"
2527
"github.com/e2b-dev/infra/packages/shared/pkg/telemetry"
2628
ut "github.com/e2b-dev/infra/packages/shared/pkg/utils"
2729
)
2830

31+
const internetBlockCIDR = "0.0.0.0/0"
32+
33+
// Convert a list of string addresses to the SetData type
34+
func addressStringsToCIDRs(addressStrings []string) []string {
35+
data := make([]string, 0, len(addressStrings))
36+
37+
for _, addressString := range addressStrings {
38+
if !strings.Contains(addressString, "/") {
39+
addressString += "/32"
40+
}
41+
data = append(data, addressString)
42+
}
43+
44+
return data
45+
}
46+
47+
// buildNetworkConfig constructs the orchestrator network configuration from the input parameters
48+
func buildNetworkConfig(network *types.SandboxNetworkConfig, allowInternetAccess *bool) *orchestrator.SandboxNetworkConfig {
49+
orchNetwork := &orchestrator.SandboxNetworkConfig{
50+
Egress: &orchestrator.SandboxNetworkEgressConfig{},
51+
}
52+
53+
// Copy network configuration if provided
54+
if network != nil && network.Egress != nil {
55+
orchNetwork.Egress.AllowedCidrs = addressStringsToCIDRs(network.Egress.AllowedAddresses)
56+
orchNetwork.Egress.DeniedCidrs = addressStringsToCIDRs(network.Egress.DeniedAddresses)
57+
}
58+
59+
// Handle the case where internet access is explicitly disabled
60+
// This should be applied after copying the network config to preserve allowed addresses
61+
if allowInternetAccess != nil && !*allowInternetAccess {
62+
// Block all internet access - this overrides any other blocked addresses
63+
orchNetwork.Egress.DeniedCidrs = []string{internetBlockCIDR}
64+
}
65+
66+
return orchNetwork
67+
}
68+
2969
func (o *Orchestrator) CreateSandbox(
3070
ctx context.Context,
3171
sandboxID,
3272
executionID,
3373
alias string,
34-
team *types.Team,
74+
team *teamtypes.Team,
3575
build queries.EnvBuild,
3676
metadata map[string]string,
3777
envVars map[string]string,
@@ -44,6 +84,7 @@ func (o *Orchestrator) CreateSandbox(
4484
autoPause bool,
4585
envdAuthToken *string,
4686
allowInternetAccess *bool,
87+
network *types.SandboxNetworkConfig,
4788
) (sbx sandbox.Sandbox, apiErr *api.APIError) {
4889
ctx, childSpan := tracer.Start(ctx, "create-sandbox")
4990
defer childSpan.End()
@@ -138,6 +179,8 @@ func (o *Orchestrator) CreateSandbox(
138179
sbxDomain = cluster.SandboxDomain
139180
}
140181

182+
sbxNetwork := buildNetworkConfig(network, allowInternetAccess)
183+
141184
sbxRequest := &orchestrator.SandboxCreateRequest{
142185
Sandbox: &orchestrator.SandboxConfig{
143186
BaseTemplateId: baseTemplateID,
@@ -160,6 +203,7 @@ func (o *Orchestrator) CreateSandbox(
160203
Snapshot: isResume,
161204
AutoPause: autoPause,
162205
AllowInternetAccess: allowInternetAccess,
206+
Network: sbxNetwork,
163207
TotalDiskSizeMb: ut.FromPtr(build.TotalDiskSizeMb),
164208
},
165209
StartTime: timestamppb.New(startTime),
@@ -237,6 +281,7 @@ func (o *Orchestrator) CreateSandbox(
237281
allowInternetAccess,
238282
baseTemplateID,
239283
sbxDomain,
284+
network,
240285
)
241286

242287
o.sandboxStore.Add(ctx, sbx, true)

packages/api/internal/orchestrator/nodemanager/sandboxes.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/e2b-dev/infra/packages/api/internal/sandbox"
1212
"github.com/e2b-dev/infra/packages/api/internal/utils"
13+
"github.com/e2b-dev/infra/packages/db/types"
1314
"github.com/e2b-dev/infra/packages/shared/pkg/consts"
1415
)
1516

@@ -46,6 +47,13 @@ func (n *Node) GetSandboxes(ctx context.Context) ([]sandbox.Sandbox, error) {
4647
return nil, fmt.Errorf("failed to parse build ID '%s' for job: %w", config.GetBuildId(), parseErr)
4748
}
4849

50+
network := &types.SandboxNetworkConfig{
51+
Egress: &types.SandboxNetworkEgressConfig{
52+
AllowedAddresses: config.GetNetwork().GetEgress().GetAllowedCidrs(),
53+
DeniedAddresses: config.GetNetwork().GetEgress().GetDeniedCidrs(),
54+
},
55+
}
56+
4957
sandboxesInfo = append(
5058
sandboxesInfo,
5159
sandbox.NewSandbox(
@@ -73,6 +81,7 @@ func (n *Node) GetSandboxes(ctx context.Context) ([]sandbox.Sandbox, error) {
7381
config.AllowInternetAccess, //nolint:protogetter // we need the nil check too
7482
config.GetBaseTemplateId(),
7583
n.SandboxDomain,
84+
network,
7685
),
7786
)
7887
}

packages/api/internal/orchestrator/pause_instance.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ func (o *Orchestrator) pauseSandbox(ctx context.Context, node *nodemanager.Node,
4343
EnvdSecured: sbx.EnvdAccessToken != nil,
4444
AllowInternetAccess: sbx.AllowInternetAccess,
4545
AutoPause: sbx.AutoPause,
46+
Config: &types.PausedSandboxConfig{
47+
Version: types.PausedSandboxConfigVersion,
48+
Network: sbx.Network,
49+
},
4650
}
4751

4852
envBuild, err := o.dbClient.NewSnapshotBuild(

0 commit comments

Comments
 (0)