Skip to content

Commit 8f772c7

Browse files
feat: Network manager
1 parent f3e7fa7 commit 8f772c7

File tree

4 files changed

+78
-173
lines changed

4 files changed

+78
-173
lines changed

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 18
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-7c27e323412e72166bce2de104f1bf82b57197e05b686e94cd81d07e288bd558.yml
3-
openapi_spec_hash: 4656d2b318d04a9fec0210897d76b505
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-2d26027dfc3e310d3004f117e7a2834be18bdb5054b034262b2caa4c69b78f79.yml
3+
openapi_spec_hash: 02e0e42393d3a95414878cdd23d1f5ad
44
config_hash: 35db4c99791f175865381f13a8ad6075

api.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,9 @@ Methods:
2323

2424
# Instances
2525

26-
Params Types:
27-
28-
- <a href="https://pkg.go.dev/github.com/onkernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/onkernel/hypeman-go#PortMappingParam">PortMappingParam</a>
29-
- <a href="https://pkg.go.dev/github.com/onkernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/onkernel/hypeman-go#VolumeAttachmentParam">VolumeAttachmentParam</a>
30-
3126
Response Types:
3227

3328
- <a href="https://pkg.go.dev/github.com/onkernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/onkernel/hypeman-go#Instance">Instance</a>
34-
- <a href="https://pkg.go.dev/github.com/onkernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/onkernel/hypeman-go#PortMapping">PortMapping</a>
35-
- <a href="https://pkg.go.dev/github.com/onkernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/onkernel/hypeman-go#VolumeAttachment">VolumeAttachment</a>
3629

3730
Methods:
3831

instance.go

Lines changed: 68 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package hypeman
44

55
import (
66
"context"
7-
"encoding/json"
87
"errors"
98
"fmt"
109
"net/http"
@@ -125,11 +124,11 @@ func (r *InstanceService) StreamLogsStreaming(ctx context.Context, id string, qu
125124
}
126125

127126
type Instance struct {
128-
// Unique identifier
127+
// Auto-generated unique identifier (CUID2 format)
129128
ID string `json:"id,required"`
130129
// Creation timestamp (RFC3339)
131130
CreatedAt time.Time `json:"created_at,required" format:"date-time"`
132-
// Image identifier
131+
// OCI image reference
133132
Image string `json:"image,required"`
134133
// Human-readable name
135134
Name string `json:"name,required"`
@@ -146,49 +145,40 @@ type Instance struct {
146145
State InstanceState `json:"state,required"`
147146
// Environment variables
148147
Env map[string]string `json:"env"`
149-
// Fully qualified domain name
150-
Fqdn string `json:"fqdn,nullable"`
151148
// Whether a snapshot exists for this instance
152149
HasSnapshot bool `json:"has_snapshot"`
153-
// Configured maximum memory in MB
154-
MemoryMaxMB int64 `json:"memory_max_mb"`
155-
// Configured base memory in MB
156-
MemoryMB int64 `json:"memory_mb"`
157-
// Port mappings
158-
PortMappings []PortMapping `json:"port_mappings"`
159-
// Private IP address
160-
PrivateIP string `json:"private_ip,nullable"`
150+
// Hotplug memory size (human-readable)
151+
HotplugSize string `json:"hotplug_size"`
152+
// Network configuration of the instance
153+
Network InstanceNetwork `json:"network"`
154+
// Writable overlay disk size (human-readable)
155+
OverlaySize string `json:"overlay_size"`
156+
// Base memory size (human-readable)
157+
Size string `json:"size"`
161158
// Start timestamp (RFC3339)
162159
StartedAt time.Time `json:"started_at,nullable" format:"date-time"`
163160
// Stop timestamp (RFC3339)
164161
StoppedAt time.Time `json:"stopped_at,nullable" format:"date-time"`
165-
// Timeout configuration
166-
TimeoutSeconds int64 `json:"timeout_seconds"`
167162
// Number of virtual CPUs
168163
Vcpus int64 `json:"vcpus"`
169-
// Attached volumes
170-
Volumes []VolumeAttachment `json:"volumes"`
171164
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
172165
JSON struct {
173-
ID respjson.Field
174-
CreatedAt respjson.Field
175-
Image respjson.Field
176-
Name respjson.Field
177-
State respjson.Field
178-
Env respjson.Field
179-
Fqdn respjson.Field
180-
HasSnapshot respjson.Field
181-
MemoryMaxMB respjson.Field
182-
MemoryMB respjson.Field
183-
PortMappings respjson.Field
184-
PrivateIP respjson.Field
185-
StartedAt respjson.Field
186-
StoppedAt respjson.Field
187-
TimeoutSeconds respjson.Field
188-
Vcpus respjson.Field
189-
Volumes respjson.Field
190-
ExtraFields map[string]respjson.Field
191-
raw string
166+
ID respjson.Field
167+
CreatedAt respjson.Field
168+
Image respjson.Field
169+
Name respjson.Field
170+
State respjson.Field
171+
Env respjson.Field
172+
HasSnapshot respjson.Field
173+
HotplugSize respjson.Field
174+
Network respjson.Field
175+
OverlaySize respjson.Field
176+
Size respjson.Field
177+
StartedAt respjson.Field
178+
StoppedAt respjson.Field
179+
Vcpus respjson.Field
180+
ExtraFields map[string]respjson.Field
181+
raw string
192182
} `json:"-"`
193183
}
194184

@@ -217,136 +207,51 @@ const (
217207
InstanceStateStandby InstanceState = "Standby"
218208
)
219209

220-
type PortMapping struct {
221-
// Port in the guest VM
222-
GuestPort int64 `json:"guest_port,required"`
223-
// Port on the host
224-
HostPort int64 `json:"host_port,required"`
225-
// Any of "tcp", "udp".
226-
Protocol PortMappingProtocol `json:"protocol"`
210+
// Network configuration of the instance
211+
type InstanceNetwork struct {
212+
// Whether instance is attached to the default network
213+
Enabled bool `json:"enabled"`
214+
// Assigned IP address (null if no network)
215+
IP string `json:"ip,nullable"`
216+
// Assigned MAC address (null if no network)
217+
Mac string `json:"mac,nullable"`
218+
// Network name (always "default" when enabled)
219+
Name string `json:"name"`
227220
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
228221
JSON struct {
229-
GuestPort respjson.Field
230-
HostPort respjson.Field
231-
Protocol respjson.Field
222+
Enabled respjson.Field
223+
IP respjson.Field
224+
Mac respjson.Field
225+
Name respjson.Field
232226
ExtraFields map[string]respjson.Field
233227
raw string
234228
} `json:"-"`
235229
}
236230

237231
// Returns the unmodified JSON received from the API
238-
func (r PortMapping) RawJSON() string { return r.JSON.raw }
239-
func (r *PortMapping) UnmarshalJSON(data []byte) error {
240-
return apijson.UnmarshalRoot(data, r)
241-
}
242-
243-
// ToParam converts this PortMapping to a PortMappingParam.
244-
//
245-
// Warning: the fields of the param type will not be present. ToParam should only
246-
// be used at the last possible moment before sending a request. Test for this with
247-
// PortMappingParam.Overrides()
248-
func (r PortMapping) ToParam() PortMappingParam {
249-
return param.Override[PortMappingParam](json.RawMessage(r.RawJSON()))
250-
}
251-
252-
type PortMappingProtocol string
253-
254-
const (
255-
PortMappingProtocolTcp PortMappingProtocol = "tcp"
256-
PortMappingProtocolUdp PortMappingProtocol = "udp"
257-
)
258-
259-
// The properties GuestPort, HostPort are required.
260-
type PortMappingParam struct {
261-
// Port in the guest VM
262-
GuestPort int64 `json:"guest_port,required"`
263-
// Port on the host
264-
HostPort int64 `json:"host_port,required"`
265-
// Any of "tcp", "udp".
266-
Protocol PortMappingProtocol `json:"protocol,omitzero"`
267-
paramObj
268-
}
269-
270-
func (r PortMappingParam) MarshalJSON() (data []byte, err error) {
271-
type shadow PortMappingParam
272-
return param.MarshalObject(r, (*shadow)(&r))
273-
}
274-
func (r *PortMappingParam) UnmarshalJSON(data []byte) error {
275-
return apijson.UnmarshalRoot(data, r)
276-
}
277-
278-
type VolumeAttachment struct {
279-
// Path where volume is mounted in the guest
280-
MountPath string `json:"mount_path,required"`
281-
// Volume identifier
282-
VolumeID string `json:"volume_id,required"`
283-
// Whether volume is mounted read-only
284-
Readonly bool `json:"readonly"`
285-
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
286-
JSON struct {
287-
MountPath respjson.Field
288-
VolumeID respjson.Field
289-
Readonly respjson.Field
290-
ExtraFields map[string]respjson.Field
291-
raw string
292-
} `json:"-"`
293-
}
294-
295-
// Returns the unmodified JSON received from the API
296-
func (r VolumeAttachment) RawJSON() string { return r.JSON.raw }
297-
func (r *VolumeAttachment) UnmarshalJSON(data []byte) error {
298-
return apijson.UnmarshalRoot(data, r)
299-
}
300-
301-
// ToParam converts this VolumeAttachment to a VolumeAttachmentParam.
302-
//
303-
// Warning: the fields of the param type will not be present. ToParam should only
304-
// be used at the last possible moment before sending a request. Test for this with
305-
// VolumeAttachmentParam.Overrides()
306-
func (r VolumeAttachment) ToParam() VolumeAttachmentParam {
307-
return param.Override[VolumeAttachmentParam](json.RawMessage(r.RawJSON()))
308-
}
309-
310-
// The properties MountPath, VolumeID are required.
311-
type VolumeAttachmentParam struct {
312-
// Path where volume is mounted in the guest
313-
MountPath string `json:"mount_path,required"`
314-
// Volume identifier
315-
VolumeID string `json:"volume_id,required"`
316-
// Whether volume is mounted read-only
317-
Readonly param.Opt[bool] `json:"readonly,omitzero"`
318-
paramObj
319-
}
320-
321-
func (r VolumeAttachmentParam) MarshalJSON() (data []byte, err error) {
322-
type shadow VolumeAttachmentParam
323-
return param.MarshalObject(r, (*shadow)(&r))
324-
}
325-
func (r *VolumeAttachmentParam) UnmarshalJSON(data []byte) error {
232+
func (r InstanceNetwork) RawJSON() string { return r.JSON.raw }
233+
func (r *InstanceNetwork) UnmarshalJSON(data []byte) error {
326234
return apijson.UnmarshalRoot(data, r)
327235
}
328236

329237
type InstanceNewParams struct {
330-
// Unique identifier for the instance (provided by caller)
331-
ID string `json:"id,required"`
332-
// Image identifier
238+
// OCI image reference
333239
Image string `json:"image,required"`
334-
// Human-readable name
240+
// Human-readable name (lowercase letters, digits, and dashes only; cannot start or
241+
// end with a dash)
335242
Name string `json:"name,required"`
336-
// Maximum memory with hotplug in MB
337-
MemoryMaxMB param.Opt[int64] `json:"memory_max_mb,omitzero"`
338-
// Base memory in MB
339-
MemoryMB param.Opt[int64] `json:"memory_mb,omitzero"`
340-
// Timeout for scale-to-zero semantics
341-
TimeoutSeconds param.Opt[int64] `json:"timeout_seconds,omitzero"`
243+
// Additional memory for hotplug (human-readable format like "3GB", "1G")
244+
HotplugSize param.Opt[string] `json:"hotplug_size,omitzero"`
245+
// Writable overlay disk size (human-readable format like "10GB", "50G")
246+
OverlaySize param.Opt[string] `json:"overlay_size,omitzero"`
247+
// Base memory size (human-readable format like "1GB", "512MB", "2G")
248+
Size param.Opt[string] `json:"size,omitzero"`
342249
// Number of virtual CPUs
343250
Vcpus param.Opt[int64] `json:"vcpus,omitzero"`
344251
// Environment variables
345252
Env map[string]string `json:"env,omitzero"`
346-
// Port mappings from host to guest
347-
PortMappings []PortMappingParam `json:"port_mappings,omitzero"`
348-
// Volumes to attach
349-
Volumes []VolumeAttachmentParam `json:"volumes,omitzero"`
253+
// Network configuration for the instance
254+
Network InstanceNewParamsNetwork `json:"network,omitzero"`
350255
paramObj
351256
}
352257

@@ -358,6 +263,21 @@ func (r *InstanceNewParams) UnmarshalJSON(data []byte) error {
358263
return apijson.UnmarshalRoot(data, r)
359264
}
360265

266+
// Network configuration for the instance
267+
type InstanceNewParamsNetwork struct {
268+
// Whether to attach instance to the default network
269+
Enabled param.Opt[bool] `json:"enabled,omitzero"`
270+
paramObj
271+
}
272+
273+
func (r InstanceNewParamsNetwork) MarshalJSON() (data []byte, err error) {
274+
type shadow InstanceNewParamsNetwork
275+
return param.MarshalObject(r, (*shadow)(&r))
276+
}
277+
func (r *InstanceNewParamsNetwork) UnmarshalJSON(data []byte) error {
278+
return apijson.UnmarshalRoot(data, r)
279+
}
280+
361281
type InstanceStreamLogsParams struct {
362282
// Follow logs (stream with SSE)
363283
Follow param.Opt[bool] `query:"follow,omitzero" json:"-"`

instance_test.go

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,19 @@ func TestInstanceNewWithOptionalParams(t *testing.T) {
2727
option.WithAPIKey("My API Key"),
2828
)
2929
_, err := client.Instances.New(context.TODO(), hypeman.InstanceNewParams{
30-
ID: "inst-abc123",
31-
Image: "img-chrome-v1",
30+
Image: "docker.io/library/alpine:latest",
3231
Name: "my-workload-1",
3332
Env: map[string]string{
3433
"PORT": "3000",
3534
"NODE_ENV": "production",
3635
},
37-
MemoryMaxMB: hypeman.Int(4096),
38-
MemoryMB: hypeman.Int(2048),
39-
PortMappings: []hypeman.PortMappingParam{{
40-
GuestPort: 80,
41-
HostPort: 8080,
42-
Protocol: hypeman.PortMappingProtocolTcp,
43-
}},
44-
TimeoutSeconds: hypeman.Int(7200),
45-
Vcpus: hypeman.Int(2),
46-
Volumes: []hypeman.VolumeAttachmentParam{{
47-
MountPath: "/mnt/data",
48-
VolumeID: "vol-abc123",
49-
Readonly: hypeman.Bool(true),
50-
}},
36+
HotplugSize: hypeman.String("2GB"),
37+
Network: hypeman.InstanceNewParamsNetwork{
38+
Enabled: hypeman.Bool(true),
39+
},
40+
OverlaySize: hypeman.String("20GB"),
41+
Size: hypeman.String("2GB"),
42+
Vcpus: hypeman.Int(2),
5143
})
5244
if err != nil {
5345
var apierr *hypeman.Error

0 commit comments

Comments
 (0)