Skip to content

Commit c00e3ad

Browse files
authored
Merge pull request #39 from serverscom/add-network-methods
add ds network methods
2 parents 178543e + e9bcbfc commit c00e3ad

5 files changed

Lines changed: 311 additions & 2 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"id": "pen5zld7",
3+
"title": "Public",
4+
"status": "active",
5+
"cidr": "100.0.8.0/29",
6+
"family": "ipv4",
7+
"interface_type": "public",
8+
"distribution_method": "gateway",
9+
"additional": false,
10+
"created_at": "2025-07-31T11:03:36Z",
11+
"updated_at": "2025-07-31T11:03:36Z"
12+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"type": "traffic",
3+
"utilization": {
4+
"value": 2000000,
5+
"commit": 1000000,
6+
"unit": "KB"
7+
}
8+
}

pkg/hosts.go

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ const (
2626
dedicatedServerPTRRecordDeletePath = "/hosts/dedicated_servers/%s/ptr_records/%s"
2727
dedicatedServerReinstallPath = "/hosts/dedicated_servers/%s/reinstall"
2828

29+
// ds networks
30+
dedicatedServerNetworkUsagePath = "/hosts/dedicated_servers/%s/network_utilization"
31+
dedicatedServerNetworkPath = "/hosts/dedicated_servers/%s/networks/%s"
32+
dedicatedServerAddPublicIPv4NetworkPath = "/hosts/dedicated_servers/%s/networks/public_ipv4"
33+
dedicatedServerAddPrivateIPv4NetworkPath = "/hosts/dedicated_servers/%s/networks/private_ipv4"
34+
dedicatedServerActivatePublicIPv6Path = "/hosts/dedicated_servers/%s/networks/public_ipv6"
35+
dedicatedServerDeleteNetworkPath = "/hosts/dedicated_servers/%s/networks/%s"
36+
2937
kubernetesBaremetalNodePath = "/hosts/kubernetes_baremetal_nodes/%s"
3038
kubernetesBaremetalNodePowerOnPath = "/hosts/kubernetes_baremetal_nodes/%s/power_on"
3139
kubernetesBaremetalNodePowerOffPath = "/hosts/kubernetes_baremetal_nodes/%s/power_off"
@@ -73,9 +81,17 @@ type HostsService interface {
7381
PowerOffDedicatedServer(ctx context.Context, id string) (*DedicatedServer, error)
7482
PowerCycleDedicatedServer(ctx context.Context, id string) (*DedicatedServer, error)
7583
CreatePTRRecordForDedicatedServer(ctx context.Context, id string, input PTRRecordCreateInput) (*PTRRecord, error)
76-
DeletePTRRecordForDedicatedServer(ctx context.Context, hostID string, ptrRecordID string) error
84+
DeletePTRRecordForDedicatedServer(ctx context.Context, serverID string, ptrRecordID string) error
7785
ReinstallOperatingSystemForDedicatedServer(ctx context.Context, id string, input OperatingSystemReinstallInput) (*DedicatedServer, error)
7886

87+
// ds network methods
88+
GetDedicatedServerNetworkUsage(ctx context.Context, id string) (*NetworkUsage, error)
89+
GetDedicatedServerNetwork(ctx context.Context, serverID string, networkID string) (*Network, error)
90+
AddDedicatedServerPublicIPv4Network(ctx context.Context, id string, input NetworkInput) (*Network, error)
91+
AddDedicatedServerPrivateIPv4Network(ctx context.Context, id string, input NetworkInput) (*Network, error)
92+
ActivateDedicatedServerPubliIPv6Network(ctx context.Context, id string) (*Network, error)
93+
DeleteDedicatedServerNetwork(ctx context.Context, serverID string, networkID string) (*Network, error)
94+
7995
// sbm
8096
PowerOnSBMServer(ctx context.Context, id string) (*SBMServer, error)
8197
PowerOffSBMServer(ctx context.Context, id string) (*SBMServer, error)
@@ -659,3 +675,121 @@ func (h *HostsHandler) PowerCycleKubernetesBaremetalNode(ctx context.Context, id
659675

660676
return &node, nil
661677
}
678+
679+
// Get network utilization for a dedicated server
680+
// Endpoint: https://developers.servers.com/api-documentation/v1/#tag/Dedicated-Server/operation/GetNetworkUsageForADedicatedServer
681+
func (h *HostsHandler) GetDedicatedServerNetworkUsage(ctx context.Context, id string) (*NetworkUsage, error) {
682+
url := h.client.buildURL(dedicatedServerNetworkUsagePath, id)
683+
684+
body, err := h.client.buildAndExecRequest(ctx, "GET", url, nil)
685+
if err != nil {
686+
return nil, err
687+
}
688+
689+
var networkUsage NetworkUsage
690+
if err := json.Unmarshal(body, &networkUsage); err != nil {
691+
return nil, err
692+
}
693+
694+
return &networkUsage, nil
695+
}
696+
697+
// Get network details for a dedicated server
698+
// Endpoint: https://developers.servers.com/api-documentation/v1/#tag/Dedicated-Server/operation/GetANetworkForADedicatedServer
699+
func (h *HostsHandler) GetDedicatedServerNetwork(ctx context.Context, serverID, networkID string) (*Network, error) {
700+
url := h.client.buildURL(dedicatedServerNetworkPath, serverID, networkID)
701+
702+
body, err := h.client.buildAndExecRequest(ctx, "GET", url, nil)
703+
if err != nil {
704+
return nil, err
705+
}
706+
707+
var network Network
708+
if err := json.Unmarshal(body, &network); err != nil {
709+
return nil, err
710+
}
711+
712+
return &network, nil
713+
}
714+
715+
// Add a public IPv4 network to a dedicated server
716+
// Endpoint: https://developers.servers.com/api-documentation/v1/#tag/Dedicated-Server/operation/CreateAPublicIpv4NetworkForADedicatedServer
717+
func (h *HostsHandler) AddDedicatedServerPublicIPv4Network(ctx context.Context, id string, input NetworkInput) (*Network, error) {
718+
payload, err := json.Marshal(input)
719+
if err != nil {
720+
return nil, err
721+
}
722+
723+
url := h.client.buildURL(dedicatedServerAddPublicIPv4NetworkPath, id)
724+
725+
body, err := h.client.buildAndExecRequest(ctx, "POST", url, payload)
726+
if err != nil {
727+
return nil, err
728+
}
729+
730+
var network Network
731+
if err := json.Unmarshal(body, &network); err != nil {
732+
return nil, err
733+
}
734+
735+
return &network, nil
736+
}
737+
738+
// Add a private IPv4 network to a dedicated server
739+
// Endpoint: https://developers.servers.com/api-documentation/v1/#tag/Dedicated-Server/operation/CreateAPrivateIpv4NetworkForADedicatedServer
740+
func (h *HostsHandler) AddDedicatedServerPrivateIPv4Network(ctx context.Context, id string, input NetworkInput) (*Network, error) {
741+
payload, err := json.Marshal(input)
742+
if err != nil {
743+
return nil, err
744+
}
745+
746+
url := h.client.buildURL(dedicatedServerAddPrivateIPv4NetworkPath, id)
747+
748+
body, err := h.client.buildAndExecRequest(ctx, "POST", url, payload)
749+
if err != nil {
750+
return nil, err
751+
}
752+
753+
var network Network
754+
if err := json.Unmarshal(body, &network); err != nil {
755+
return nil, err
756+
}
757+
758+
return &network, nil
759+
}
760+
761+
// Activate a public IPv6 network for a dedicated server
762+
// Endpoint: https://developers.servers.com/api-documentation/v1/#tag/Dedicated-Server/operation/ActivateAPublicIpv6NetworkForADedicatedServer
763+
func (h *HostsHandler) ActivateDedicatedServerPubliIPv6Network(ctx context.Context, id string) (*Network, error) {
764+
url := h.client.buildURL(dedicatedServerActivatePublicIPv6Path, id)
765+
766+
body, err := h.client.buildAndExecRequest(ctx, "POST", url, nil)
767+
if err != nil {
768+
return nil, err
769+
}
770+
771+
var network Network
772+
if err := json.Unmarshal(body, &network); err != nil {
773+
return nil, err
774+
}
775+
776+
return &network, nil
777+
}
778+
779+
// Delete a network from a dedicated server
780+
// Endpoint: https://developers.servers.com/api-documentation/v1/#tag/Dedicated-Server/operation/DeleteANetworkForADedicatedServer
781+
func (h *HostsHandler) DeleteDedicatedServerNetwork(ctx context.Context, serverID, networkID string) (*Network, error) {
782+
url := h.client.buildURL(dedicatedServerDeleteNetworkPath, serverID, networkID)
783+
784+
body, err := h.client.buildAndExecRequest(ctx, "DELETE", url, nil)
785+
if err != nil {
786+
return nil, err
787+
}
788+
789+
var network Network
790+
if err := json.Unmarshal(body, &network); err != nil {
791+
return nil, err
792+
}
793+
794+
return &network, nil
795+
}

pkg/hosts_test.go

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import (
88
)
99

1010
const (
11-
serverID = "xkazYeJ0"
11+
serverID = "xkazYeJ0"
12+
networkID = "pen5zld7"
1213
)
1314

1415
func TestHostsEmptyCollection(t *testing.T) {
@@ -1043,3 +1044,138 @@ func TestHostsPowerCycleKubernetesBaremetalNode(t *testing.T) {
10431044
g.Expect(node.Created.String()).To(Equal("2020-04-22 06:22:02 +0000 UTC"))
10441045
g.Expect(node.Updated.String()).To(Equal("2020-04-22 06:22:02 +0000 UTC"))
10451046
}
1047+
1048+
func TestHostsGetDedicatedServerNetworkUsage(t *testing.T) {
1049+
g := NewGomegaWithT(t)
1050+
ts, client := newFakeServer().
1051+
WithRequestPath("/hosts/dedicated_servers/" + serverID + "/network_utilization").
1052+
WithRequestMethod("GET").
1053+
WithResponseBodyStubFile("fixtures/hosts/dedicated_servers/network_utilization.json").
1054+
WithResponseCode(200).
1055+
Build()
1056+
defer ts.Close()
1057+
1058+
ctx := context.TODO()
1059+
usage, err := client.Hosts.GetDedicatedServerNetworkUsage(ctx, serverID)
1060+
1061+
g.Expect(err).To(BeNil())
1062+
g.Expect(usage).ToNot(BeNil())
1063+
g.Expect(usage.Type).To(Equal("traffic"))
1064+
g.Expect(usage.Utilization).ToNot(BeNil())
1065+
g.Expect(usage.Utilization.Value).To(Equal(int64(2000000)))
1066+
g.Expect(usage.Utilization.Commit).To(Equal(int64(1000000)))
1067+
g.Expect(usage.Utilization.Unit).To(Equal("KB"))
1068+
}
1069+
1070+
func TestHostsGetDedicatedServerNetwork(t *testing.T) {
1071+
g := NewGomegaWithT(t)
1072+
ts, client := newFakeServer().
1073+
WithRequestPath("/hosts/dedicated_servers/" + serverID + "/networks/" + networkID).
1074+
WithRequestMethod("GET").
1075+
WithResponseBodyStubFile("fixtures/hosts/dedicated_servers/get_network_response.json").
1076+
WithResponseCode(200).
1077+
Build()
1078+
defer ts.Close()
1079+
1080+
ctx := context.TODO()
1081+
network, err := client.Hosts.GetDedicatedServerNetwork(ctx, serverID, networkID)
1082+
1083+
g.Expect(err).To(BeNil())
1084+
g.Expect(network).ToNot(BeNil())
1085+
g.Expect(network.ID).To(Equal(networkID))
1086+
g.Expect(*network.Title).To(Equal("Public"))
1087+
g.Expect(network.Status).To(Equal("active"))
1088+
g.Expect(*network.Cidr).To(Equal("100.0.8.0/29"))
1089+
g.Expect(network.Family).To(Equal("ipv4"))
1090+
g.Expect(network.InterfaceType).To(Equal("public"))
1091+
g.Expect(network.DistributionMethod).To(Equal("gateway"))
1092+
g.Expect(network.Additional).To(Equal(false))
1093+
g.Expect(network.Created.String()).To(Equal("2025-07-31 11:03:36 +0000 UTC"))
1094+
g.Expect(network.Updated.String()).To(Equal("2025-07-31 11:03:36 +0000 UTC"))
1095+
}
1096+
1097+
func TestHostsAddDedicatedServerPublicNetwork(t *testing.T) {
1098+
g := NewGomegaWithT(t)
1099+
1100+
ts, client := newFakeServer().
1101+
WithRequestPath("/hosts/dedicated_servers/" + serverID + "/networks/public_ipv4").
1102+
WithRequestMethod("POST").
1103+
WithResponseBodyStubFile("fixtures/hosts/dedicated_servers/get_network_response.json").
1104+
WithResponseCode(202).
1105+
Build()
1106+
1107+
defer ts.Close()
1108+
1109+
input := NetworkInput{
1110+
DistributionMethod: "gateway",
1111+
Mask: 29,
1112+
}
1113+
1114+
ctx := context.TODO()
1115+
network, err := client.Hosts.AddDedicatedServerPublicIPv4Network(ctx, serverID, input)
1116+
1117+
g.Expect(err).To(BeNil())
1118+
g.Expect(network).ToNot(BeNil())
1119+
g.Expect(network.ID).ToNot(BeEmpty())
1120+
}
1121+
1122+
func TestHostsAddDedicatedServerPrivateNetwork(t *testing.T) {
1123+
g := NewGomegaWithT(t)
1124+
1125+
ts, client := newFakeServer().
1126+
WithRequestPath("/hosts/dedicated_servers/" + serverID + "/networks/private_ipv4").
1127+
WithRequestMethod("POST").
1128+
WithResponseBodyStubFile("fixtures/hosts/dedicated_servers/get_network_response.json").
1129+
WithResponseCode(202).
1130+
Build()
1131+
1132+
defer ts.Close()
1133+
1134+
input := NetworkInput{
1135+
DistributionMethod: "gateway",
1136+
Mask: 29,
1137+
}
1138+
1139+
ctx := context.TODO()
1140+
network, err := client.Hosts.AddDedicatedServerPrivateIPv4Network(ctx, serverID, input)
1141+
1142+
g.Expect(err).To(BeNil())
1143+
g.Expect(network).ToNot(BeNil())
1144+
g.Expect(network.ID).ToNot(BeEmpty())
1145+
}
1146+
1147+
func TestHostsActivateDedicatedServerPublicIPv6Network(t *testing.T) {
1148+
g := NewGomegaWithT(t)
1149+
ts, client := newFakeServer().
1150+
WithRequestPath("/hosts/dedicated_servers/" + serverID + "/networks/public_ipv6").
1151+
WithRequestMethod("POST").
1152+
WithResponseBodyStubFile("fixtures/hosts/dedicated_servers/get_network_response.json").
1153+
WithResponseCode(202).
1154+
Build()
1155+
defer ts.Close()
1156+
1157+
ctx := context.TODO()
1158+
network, err := client.Hosts.ActivateDedicatedServerPubliIPv6Network(ctx, serverID)
1159+
1160+
g.Expect(err).To(BeNil())
1161+
g.Expect(network).ToNot(BeNil())
1162+
g.Expect(network.ID).ToNot(BeEmpty())
1163+
}
1164+
1165+
func TestHostsDeleteDedicatedServerNetwork(t *testing.T) {
1166+
g := NewGomegaWithT(t)
1167+
ts, client := newFakeServer().
1168+
WithRequestPath("/hosts/dedicated_servers/" + serverID + "/networks/" + networkID).
1169+
WithRequestMethod("DELETE").
1170+
WithResponseBodyStubFile("fixtures/hosts/dedicated_servers/get_network_response.json").
1171+
WithResponseCode(202).
1172+
Build()
1173+
defer ts.Close()
1174+
1175+
ctx := context.TODO()
1176+
network, err := client.Hosts.DeleteDedicatedServerNetwork(ctx, serverID, networkID)
1177+
1178+
g.Expect(err).To(BeNil())
1179+
g.Expect(network).ToNot(BeNil())
1180+
g.Expect(network.ID).To(Equal(networkID))
1181+
}

pkg/types.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,3 +1103,22 @@ type AccountBalance struct {
11031103
NextInvoiceTotalDue float64 `json:"next_invoice_total_due"`
11041104
Currency string `json:"currency"`
11051105
}
1106+
1107+
// NetworkInput represents network input
1108+
type NetworkInput struct {
1109+
DistributionMethod string `json:"distribution_method,omitempty"`
1110+
Mask int `json:"mask"`
1111+
}
1112+
1113+
// Utilization represents utilization info
1114+
type Utilization struct {
1115+
Value int64 `json:"value"`
1116+
Commit int64 `json:"commit"`
1117+
Unit string `json:"unit"`
1118+
}
1119+
1120+
// NetworkUsage represents network usage
1121+
type NetworkUsage struct {
1122+
Type string `json:"type"`
1123+
Utilization *Utilization `json:"utilization"`
1124+
}

0 commit comments

Comments
 (0)