Skip to content
Snippets Groups Projects
Verified Commit d9723f82 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

feat: initial implementation

parent 91cedffe
No related merge requests found
Showing
with 876 additions and 0 deletions
/.idea/
/vendor/
*.iml
package api
import (
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
)
func (c Client) GetBackup(id ServerId) (FTPBackup, error) {
var result FTPBackup
path, err := FTPBackupPath(id)
if err != nil {
return result, fmt.Errorf("api.backup: could not parse url\n %w", err)
}
request, err := http.NewRequest("GET", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return result, fmt.Errorf("api.backup: could not build request\n %w", err)
}
err = c.doRequest(request, &result)
if err != nil {
return result, fmt.Errorf("api.backup: could not get backup\n %w", err)
}
return result, nil
}
type EditBackupParams struct {
Password string
AutoLogin bool
AclEnabled bool
}
func (c Client) EditBackup(id ServerId, params EditBackupParams) error {
body := strings.NewReader(url.Values{
"password": []string{params.Password},
"autologin": []string{strconv.FormatBool(params.AutoLogin)},
"acl_enabled": []string{strconv.FormatBool(params.AclEnabled)},
}.Encode())
path, err := FTPBackupPath(id)
if err != nil {
return fmt.Errorf("api.backup: could not parse url\n %w", err)
}
request, err := http.NewRequest("PUT", c.baseUrl.ResolveReference(path).String(), body)
if err != nil {
return fmt.Errorf("api.backup: could not build request\n %w", err)
}
err = c.doRequest(request, nil)
if err != nil {
return fmt.Errorf("api.backup: could not edit backup\n %w", err)
}
return nil
}
package api
import (
"fmt"
"net/http"
"net/url"
"strings"
)
func (c Client) GetBMCSession(id ServerId) (BMCSession, error) {
var result BMCSession
path, err := BMCSessionPath(id)
if err != nil {
return result, fmt.Errorf("api.bmcsession: could not parse url\n %w", err)
}
request, err := http.NewRequest("GET", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return result, fmt.Errorf("api.bmcsession: could not build request\n %w", err)
}
err = c.doRequest(request, &result)
if err != nil {
return result, fmt.Errorf("api.bmcsession: could not get bmc session\n %w", err)
}
return result, nil
}
func (c Client) CreateBMCSession(id ServerId, authorizedIp string) error {
body := strings.NewReader(url.Values{
"ip": []string{authorizedIp},
}.Encode())
path, err := BMCSessionPath(id)
if err != nil {
return fmt.Errorf("api.bmcsession: could not parse url\n %w", err)
}
request, err := http.NewRequest("POST", c.baseUrl.ResolveReference(path).String(), body)
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
if err != nil {
return fmt.Errorf("api.bmcsession: could not build request\n %w", err)
}
err = c.doRequest(request, nil)
if err != nil {
return fmt.Errorf("api.bmcsession: could not create bmc session\n %w", err)
}
return nil
}
func (c Client) CloseBMCSession(id ServerId) error {
path, err := BMCSessionPath(id)
if err != nil {
return fmt.Errorf("api.bmcsession: could not parse url\n %w", err)
}
request, err := http.NewRequest("DELETE", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return fmt.Errorf("api.bmcsession: could not build request\n %w", err)
}
err = c.doRequest(request, nil)
if err != nil {
return fmt.Errorf("api.bmcsession: could not close bmc session\n %w", err)
}
return nil
}
package api
import (
"fmt"
"net/http"
"net/url"
)
func (c Client) GetDisk(ref DiskRef) (Disk, error) {
var result Disk
path, err := url.Parse(string(ref))
if err != nil {
return result, fmt.Errorf("api.disk: could not parse url\n %w", err)
}
request, err := http.NewRequest("GET", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return result, fmt.Errorf("api.disk: could not build request\n %w", err)
}
err = c.doRequest(request, &result)
if err != nil {
return result, fmt.Errorf("api.disk: could not get disk\n %w", err)
}
return result, nil
}
package api
import (
"fmt"
"net/http"
)
func (c Client) GetOperatingSystems(id ServerId) ([]OperatingSystem, error) {
var result []OperatingSystem
path, err := OperatingSystemPath(id)
if err != nil {
return result, fmt.Errorf("api.operatingsystem: could not parse url\n %w", err)
}
request, err := http.NewRequest("GET", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return result, fmt.Errorf("api.operatingsystem: could not build request\n %w", err)
}
err = c.doRequest(request, &result)
if err != nil {
return result, fmt.Errorf("api.operatingsystem: could not list operatingsystems\n %w", err)
}
return result, nil
}
package api
import (
"fmt"
"net/http"
)
func (c Client) GetProductInfo(id ServerId) (ProductInfo, error) {
var result ProductInfo
path, err := ProductInfoPath(id)
if err != nil {
return result, fmt.Errorf("api.productinfo: could not parse url\n %w", err)
}
request, err := http.NewRequest("GET", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return result, fmt.Errorf("api.productinfo: could not build request\n %w", err)
}
err = c.doRequest(request, &result)
if err != nil {
return result, fmt.Errorf("api.productinfo: could not get productinfo\n %w", err)
}
return result, nil
}
package api
import (
"fmt"
"net/http"
"net/url"
)
func (c Client) GetRaidController(ref RaidControllerRef) (RaidController, error) {
var result RaidController
path, err := url.Parse(string(ref))
if err != nil {
return result, fmt.Errorf("api.raidcontroller: could not parse url\n %w", err)
}
request, err := http.NewRequest("GET", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return result, fmt.Errorf("api.raidcontroller: could not build request\n %w", err)
}
err = c.doRequest(request, &result)
if err != nil {
return result, fmt.Errorf("api.raidcontroller: could not get raidcontroller\n %w", err)
}
return result, nil
}
package api
import (
"fmt"
"net/http"
)
func (c Client) GetRescueImages(id ServerId) ([]RescueImageId, error) {
var result []RescueImageId
path, err := RescueImagePath(id)
if err != nil {
return result, fmt.Errorf("api.rescueimage: could not parse url\n %w", err)
}
request, err := http.NewRequest("GET", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return result, fmt.Errorf("api.rescueimage: could not build request\n %w", err)
}
err = c.doRequest(request, &result)
if err != nil {
return result, fmt.Errorf("api.rescueimage: could not list rescueimages\n %w", err)
}
return result, nil
}
package api
import (
"fmt"
"net/http"
"net/url"
"strings"
)
func (c Client) GetServers() ([]ServerRef, error) {
var result []ServerRef
path, err := url.Parse(serverPath)
if err != nil {
return result, fmt.Errorf("api.server: could not parse url\n %w", err)
}
request, err := http.NewRequest("GET", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return result, fmt.Errorf("api.server: could not build request\n %w", err)
}
err = c.doRequest(request, &result)
if err != nil {
return result, fmt.Errorf("api.server: could not list servers\n %w", err)
}
return result, nil
}
func (c Client) GetServer(ref ServerRef) (Server, error) {
var result Server
path, err := url.Parse(string(ref))
if err != nil {
return result, fmt.Errorf("api.server: could not parse url\n %w", err)
}
request, err := http.NewRequest("GET", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return result, fmt.Errorf("api.server: could not build request\n %w", err)
}
err = c.doRequest(request, &result)
if err != nil {
return result, fmt.Errorf("api.server: could not get server\n %w", err)
}
return result, nil
}
func (c Client) UpdateServer(ref ServerRef, hostname string) error {
body := strings.NewReader(url.Values{
"hostname": []string{hostname},
}.Encode())
path, err := url.Parse(string(ref))
if err != nil {
return fmt.Errorf("api.server: could not parse url\n %w", err)
}
request, err := http.NewRequest("PUT", c.baseUrl.ResolveReference(path).String(), body)
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
if err != nil {
return fmt.Errorf("api.server: could not build request\n %w", err)
}
err = c.doRequest(request, nil)
if err != nil {
return fmt.Errorf("api.server: could not update server\n %w", err)
}
return nil
}
func (c Client) BootServerNormal(id ServerId) error {
path, err := ServerBootPath(id, BootModeNormal)
if err != nil {
return fmt.Errorf("api.server: could not parse url\n %w", err)
}
request, err := http.NewRequest("POST", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return fmt.Errorf("api.server: could not build request\n %w", err)
}
err = c.doRequest(request, nil)
if err != nil {
return fmt.Errorf("api.server: could not boot server in normal mode\n %w", err)
}
return nil
}
func (c Client) BootServerRescue(id ServerId, image RescueImageId) (RescueCredentials, error) {
var result RescueCredentials
body := strings.NewReader(url.Values{
"image": []string{string(image)},
}.Encode())
path, err := ServerBootPath(id, BootModeRescue)
if err != nil {
return result, fmt.Errorf("api.server: could not parse url\n %w", err)
}
request, err := http.NewRequest("POST", c.baseUrl.ResolveReference(path).String(), body)
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
if err != nil {
return result, fmt.Errorf("api.server: could not build request\n %w", err)
}
err = c.doRequest(request, nil)
if err != nil {
return result, fmt.Errorf("api.server: could not boot server in rescue mode\n %w", err)
}
return result, nil
}
type ServerNotificationParams struct {
Reason string
Email string
}
func (c Client) ShutdownServer(id ServerId, params ServerNotificationParams) error {
body := strings.NewReader(url.Values{
"reason": []string{params.Reason},
"email": []string{params.Email},
}.Encode())
path, err := ServerShutdownPath(id)
if err != nil {
return fmt.Errorf("api.server: could not parse url\n %w", err)
}
request, err := http.NewRequest("POST", c.baseUrl.ResolveReference(path).String(), body)
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
if err != nil {
return fmt.Errorf("api.server: could not build request\n %w", err)
}
err = c.doRequest(request, nil)
if err != nil {
return fmt.Errorf("api.server: could not shutdown server\n %w", err)
}
return nil
}
func (c Client) RebootServer(id ServerId, params ServerNotificationParams) error {
body := strings.NewReader(url.Values{
"reason": []string{params.Reason},
"email": []string{params.Email},
}.Encode())
path, err := ServerRebootPath(id)
if err != nil {
return fmt.Errorf("api.server: could not parse url\n %w", err)
}
request, err := http.NewRequest("POST", c.baseUrl.ResolveReference(path).String(), body)
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
if err != nil {
return fmt.Errorf("api.server: could not build request\n %w", err)
}
err = c.doRequest(request, nil)
if err != nil {
return fmt.Errorf("api.server: could not reboot server\n %w", err)
}
return nil
}
package api
import (
"fmt"
"net/http"
"net/url"
)
func (c Client) GetIPAddress(ref ServerIPRef) (ServerIP, error) {
var result ServerIP
path, err := url.Parse(string(ref))
if err != nil {
return result, fmt.Errorf("api.serverip: could not parse url\n %w", err)
}
request, err := http.NewRequest("GET", c.baseUrl.ResolveReference(path).String(), nil)
if err != nil {
return result, fmt.Errorf("api.serverip: could not build request\n %w", err)
}
err = c.doRequest(request, &result)
if err != nil {
return result, fmt.Errorf("api.serverip: could not get serverip\n %w", err)
}
return result, nil
}
package api
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"scaleway-dedibox-api/httputil"
)
type Client struct {
http *httputil.Client
baseUrl *url.URL
}
func NewClient(client *httputil.Client, baseUrl *url.URL) Client {
if client == nil {
client = httputil.NewClient(nil, nil)
}
return Client{
http: client,
baseUrl: baseUrl,
}
}
type parsedError struct {
Code int `json:"code"`
Error string `json:"error"`
}
func parseError(body io.ReadCloser) (parsedError, error) {
var result parsedError
return result, json.NewDecoder(body).Decode(&result)
}
func (c Client) doRequest(request *http.Request, target any) error {
response, err := c.http.Do(request)
if err != nil {
return fmt.Errorf("api: could not execute request\n %w", err)
}
if !httputil.IsHttpStatusSuccess(response.StatusCode) {
parsedError, err := parseError(response.Body)
if err != nil {
return fmt.Errorf("api: got non-success status: %s", response.Status)
} else {
return fmt.Errorf("api: got non-success status: %s, code: %d, reason: %s",
response.Status, parsedError.Code, parsedError.Error)
}
}
if target != nil {
if err := json.NewDecoder(response.Body).Decode(&target); err != nil {
return fmt.Errorf("api: could not deserialize response body\n %w", err)
}
}
return nil
}
package api
import (
"net/url"
"path"
"strconv"
)
const bmcSessionPath = "/api/v1/server/bmc/session/"
func BMCSessionPath(id ServerId) (*url.URL, error) {
return url.Parse(path.Join(bmcSessionPath, strconv.Itoa(int(id))))
}
type BMCSession struct {
Url string `json:"url,omitempty"`
Login string `json:"login,omitempty"`
Password string `json:"password,omitempty"`
Expiration *TimeDto `json:"expiration,omitempty"`
}
package api
import (
"fmt"
"path"
"strconv"
)
type DiskId int
type DiskRef string
const diskPath = "/api/v1/server/hardware/disk/"
func ToDiskRef(id DiskId) DiskRef {
return DiskRef(path.Join(diskPath, strconv.Itoa(int(id))))
}
func ToDiskId(ref DiskRef) (DiskId, error) {
prefix, id := path.Split(string(ref))
if prefix != diskPath {
return 0, fmt.Errorf("api.model_disk: invalid disk ref %s", ref)
}
parsed, err := strconv.Atoi(id)
if err != nil {
return 0, fmt.Errorf("api.model_disk: invalid disk ref %s\n %w", ref, err)
}
return DiskId(parsed), nil
}
type DiskType = string
const (
DiskTypeSATA DiskType = "SATA"
DiskTypeSAS DiskType = "SAS"
DiskTypeSSHD DiskType = "SSHD"
DiskTypeNVME DiskType = "NVME"
)
type Disk struct {
Id DiskId `json:"id,omitempty"`
Connector string `json:"connector,omitempty"`
Type DiskType `json:"type,omitempty"`
Capacity int `json:"capacity,omitempty"`
RaidController WrappedRef[RaidControllerRef] `json:"raid_controller,omitempty"`
}
package api
import (
"net/url"
"path"
"strconv"
)
const ftpBackupPath = "/api/v1/server/backup/"
func FTPBackupPath(id ServerId) (*url.URL, error) {
return url.Parse(path.Join(ftpBackupPath, strconv.Itoa(int(id))))
}
type FTPBackup struct {
Login string `json:"login,omitempty"`
Server string `json:"server,omitempty"`
Active bool `json:"active,omitempty"`
AclEnabled bool `json:"acl_enabled,omitempty"`
AutoLogin bool `json:"auto_login,omitempty"`
QuotaSpace int `json:"quota_space,omitempty"`
QuotaSpaceUsed int `json:"quota_space_used,omitempty"`
QuotaFiles int `json:"quota_files,omitempty"`
QuotaFilesUsed int `json:"quota_files_used,omitempty"`
}
package api
import (
"net/url"
"path"
"strconv"
"time"
)
type OperatingSystemId = int
const operatingSystemPath = "/api/v1/server/operatingSystems/"
func OperatingSystemPath(id ServerId) (*url.URL, error) {
return url.Parse(path.Join(operatingSystemPath, strconv.Itoa(int(id))))
}
type OperatingSystemType = string
const (
OperatingSystemTypeServer OperatingSystemType = "server"
OperatingSystemTypePanel OperatingSystemType = "panel"
OperatingSystemTypeDesktop OperatingSystemType = "desktop"
OperatingSystemTypeLive OperatingSystemType = "live"
OperatingSystemTypeCustom OperatingSystemType = "custom"
OperatingSystemTypeVirtualization OperatingSystemType = "virtualization"
)
type OperatingSystemArch = string
const (
OperatingSystemArch32bit OperatingSystemArch = "32 bits"
OperatingSystemArch64bit OperatingSystemArch = "64 bits"
)
type OperatingSystem struct {
Id OperatingSystemId `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Version string `json:"version,omitempty"`
Type OperatingSystemType `json:"type,omitempty"`
Arch OperatingSystemArch `json:"arch,omitempty"`
Release *time.Time `json:"release,omitempty"`
EndOfLife *time.Time `json:"end_of_life,omitempty"`
}
package api
import (
"net/url"
"path"
"strconv"
)
const productInfoPath = "/api/v1/server/product/"
func ProductInfoPath(id ServerId) (*url.URL, error) {
return url.Parse(path.Join(productInfoPath, strconv.Itoa(int(id))))
}
type ProductInfo struct {
ProductId int `json:"product_id"`
Name string `json:"name,omitempty"`
Price int `json:"price,omitempty"`
}
package api
import (
"fmt"
"path"
"strconv"
)
type RaidControllerId int
type RaidControllerRef string
const raidControllerPath = "/api/v1/server/hardware/raidController/"
func ToRaidControllerRef(id RaidControllerId) RaidControllerRef {
return RaidControllerRef(path.Join(raidControllerPath, strconv.Itoa(int(id))))
}
func ToRaidControllerId(ref RaidControllerRef) (RaidControllerId, error) {
prefix, id := path.Split(string(ref))
if prefix != diskPath {
return 0, fmt.Errorf("api.model_raidcontroller: invalid raid controller ref %s", ref)
}
parsed, err := strconv.Atoi(id)
if err != nil {
return 0, fmt.Errorf("api.model_raidcontroller: invalid raid controller ref %s\n %w", ref, err)
}
return RaidControllerId(parsed), nil
}
type RaidLevel string
const (
RaidLevelNone RaidLevel = "NORAID"
RaidLevel0 RaidLevel = "RAID0"
RaidLevel1 RaidLevel = "RAID1"
RaidLevel5 RaidLevel = "RAID5"
RaidLevel6 RaidLevel = "RAID6"
)
type SupportedRaidLevel struct {
RaidLevel RaidLevel `json:"raid_level,omitempty"`
Min int `json:"min,omitempty"`
Max int `json:"max,omitempty"`
}
type RaidController struct {
Id RaidControllerId `json:"id,omitempty"`
Model string `json:"model,omitempty"`
Disks []Disk `json:"disks,omitempty"`
SupportedRaidLevels []SupportedRaidLevel `json:"supported_raid_levels,omitempty"`
}
package api
import (
"net/url"
"path"
"strconv"
)
const rescueImagePath = "/api/v1/server/rescue_images/"
type RescueImageId string
func RescueImagePath(id ServerId) (*url.URL, error) {
return url.Parse(path.Join(rescueImagePath, strconv.Itoa(int(id))))
}
package api
import (
"fmt"
"net"
"net/url"
"path"
"strconv"
"time"
)
type ServerId int
type ServerRef string
const serverPath = "/api/v1/server/"
const serverBootPath = "/api/v1/server/boot/"
const serverShutdownPath = "/api/v1/server/shutdown/"
const serverRebootPath = "/api/v1/server/reboot/"
func ToServerRef(id ServerId) ServerRef {
return ServerRef(path.Join(serverPath, strconv.Itoa(int(id))))
}
func ToServerId(ref ServerRef) (ServerId, error) {
prefix, id := path.Split(string(ref))
if prefix != diskPath {
return 0, fmt.Errorf("api.model_server: invalid server ref %s", ref)
}
parsed, err := strconv.Atoi(id)
if err != nil {
return 0, fmt.Errorf("api.model_server: invalid server ref %s\n %w", ref, err)
}
return ServerId(parsed), nil
}
type BootMode string
const (
BootModeNormal BootMode = "normal"
BootModeTest BootMode = "test"
BootModeRescue BootMode = "rescue"
)
func ServerBootPath(id ServerId, mode BootMode) (*url.URL, error) {
return url.Parse(path.Join(serverBootPath, string(mode), strconv.Itoa(int(id))))
}
func ServerShutdownPath(id ServerId) (*url.URL, error) {
return url.Parse(path.Join(serverShutdownPath, strconv.Itoa(int(id))))
}
func ServerRebootPath(id ServerId) (*url.URL, error) {
return url.Parse(path.Join(serverRebootPath, strconv.Itoa(int(id))))
}
type Location struct {
Datacenter string `json:"datacenter,omitempty"`
Room string `json:"room,omitempty"`
Zone string `json:"zone,omitempty"`
Line string `json:"line,omitempty"`
Rack string `json:"rack,omitempty"`
Block string `json:"block,omitempty"`
Position int `json:"position,omitempty"`
}
type Contacts struct {
Owner string `json:"owner,omitempty"`
Tech string `json:"tech,omitempty"`
}
type RescueProtocol string
const (
RescueProtocolSsh RescueProtocol = "ssh"
RescueProtocolVnc RescueProtocol = "vnc"
)
type RescueCredentials struct {
Login string `json:"login,omitempty"`
Password string `json:"password,omitempty"`
Protocol RescueProtocol `json:"protocol,omitempty"`
IP net.IP `json:"ip,omitempty"`
}
type ServerBMC struct {
SessionKey string `json:"session_key,omitempty"`
}
type DriveArray struct {
RaidLevel RaidLevel `json:"raid_level,omitempty"`
}
type InstallStatus string
const (
InstallStatusBlank InstallStatus = "blank"
InstallStatusInstalling InstallStatus = "installing"
InstallStatusInstalled InstallStatus = "installed"
InstallStatusErrored InstallStatus = "errored"
)
type InstallStage string
const (
ServerStageBoot InstallStage = "BOOT"
ServerStageWget InstallStage = "WGET"
ServerStageOs InstallStage = "OS"
ServerStageConfig InstallStage = "CONFIG"
ServerStageStart InstallStage = "START"
ServerStageCleanRaid InstallStage = "CLEAN_RAID"
ServerStageFdisk InstallStage = "FDISK"
ServerStageFormat InstallStage = "FORMAT"
ServerStageBootloader InstallStage = "BOOTLOADER"
ServerStageRebooting InstallStage = "REBOOTING"
)
type Server struct {
Id ServerId `json:"id,omitempty"`
Offer string `json:"offer,omitempty"`
Hostname string `json:"hostname,omitempty"`
OperatingSystem OperatingSystem `json:"os,omitempty"`
Power string `json:"power,omitempty"`
BootMode BootMode `json:"boot_mode,omitempty"`
LastReboot *time.Time `json:"last_reboot,omitempty"`
AntiDdos bool `json:"anti_ddos"`
HardwareWatch bool `json:"hardware_watch"`
ProactiveMonitoring bool `json:"proactive_monitoring"`
Support string `json:"support,omitempty"`
Abuse string `json:"abuse,omitempty"`
Location Location `json:"location,omitempty"`
IP []ServerIP `json:"ip,omitempty"`
Contacts Contacts `json:"contacts,omitempty"`
RescueCredentials RescueCredentials `json:"rescue_credentials,omitempty"`
Bmc ServerBMC `json:"bmc,omitempty"`
Disks []WrappedRef[DiskRef] `json:"disks,omitempty"`
DriveArrays []DriveArray `json:"drive_arrays,omitempty"`
RaidControllers []WrappedRef[RaidControllerRef] `json:"raid_controllers,omitempty"`
InstallStatus InstallStatus `json:"install_status,omitempty"`
Stage InstallStage `json:"stage,omitempty"`
}
package api
import (
"net"
"path"
)
const serverIPPath = "/api/v1/server/ip/"
type ServerIPRef string
func ToServerIPRef(ip net.IP) ServerIPRef {
return ServerIPRef(path.Join(serverIPPath, ip.String()))
}
type ServerIPType string
const (
ServerIPTypePublic ServerIPType = "public"
ServerIPTypePrivate ServerIPType = "private"
ServerIPTypeFailover ServerIPType = "failover"
)
type ServerIPStatus string
const (
ServerIPStatusActive ServerIPStatus = "active"
ServerIPStatusUpdating ServerIPStatus = "updating"
)
type ServerIP struct {
Address net.IP `json:"address,omitempty"`
Type ServerIPType `json:"type,omitempty"`
Reverse string `json:"reverse,omitempty"`
MacAddress string `json:"mac,omitempty"`
Destination net.IP `json:"destination,omitempty"`
Status ServerIPStatus `json:"status,omitempty"`
SwitchPortState string `json:"switch_port_state,omitempty"`
Server WrappedRef[ServerRef] `json:"server,omitempty"`
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment