blob: 2f435cdb3f4a0ae506b3df14a350f0eb2ddae6f6 [file] [log] [blame]
package tc
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import (
"database/sql/driver"
"encoding/json"
"errors"
"fmt"
"net"
"strconv"
"strings"
"time"
"github.com/apache/trafficcontrol/lib/go-util"
)
// ServersV4Response is the format of a response to a GET request for API v4.x /servers.
type ServersV4Response struct {
Response []ServerV40 `json:"response"`
Summary struct {
Count uint64 `json:"count"`
} `json:"summary"`
Alerts
}
// ServersV3Response is the format of a response to a GET request for /servers.
type ServersV3Response struct {
Response []ServerV30 `json:"response"`
Summary struct {
Count uint64 `json:"count"`
} `json:"summary"`
Alerts
}
// ServersResponse is a list of Servers as a response to an API v2 request.
// This can't change because it will break ORT. Unfortunately.
type ServersResponse struct {
Response []Server `json:"response"`
Alerts
}
// ServersDetailResponse is the JSON object returned for a single server.
type ServersDetailResponse struct {
Response Server `json:"response"`
Alerts
}
// ServerDetailV11 is the type of each entry in the `response` array property
// of responses from Traffic Ops to GET requests made to its /servers/details
// API endpoint in API version 2.0.
//
// The reason it's named with "V11" is because it was originally used to model
// the response in API version 1.1, and the structure simply hasn't changed
// between then and 2.0.
type ServerDetailV11 struct {
ServerDetail
LegacyInterfaceDetails
RouterHostName *string `json:"routerHostName" db:"router_host_name"`
RouterPortName *string `json:"routerPortName" db:"router_port_name"`
}
// ServerDetailV30 is the details for a server for API v3.
type ServerDetailV30 struct {
ServerDetail
ServerInterfaces *[]ServerInterfaceInfo `json:"interfaces"`
RouterHostName *string `json:"routerHostName" db:"router_host_name"`
RouterPortName *string `json:"routerPortName" db:"router_port_name"`
}
// ServerDetailV40 is the details for a server for API v4.
type ServerDetailV40 struct {
CacheGroup *string `json:"cachegroup" db:"cachegroup"`
CDNName *string `json:"cdnName" db:"cdn_name"`
DeliveryServiceIDs []int64 `json:"deliveryservices,omitempty"`
DomainName *string `json:"domainName" db:"domain_name"`
GUID *string `json:"guid" db:"guid"`
HardwareInfo map[string]string `json:"hardwareInfo"`
HostName *string `json:"hostName" db:"host_name"`
HTTPSPort *int `json:"httpsPort" db:"https_port"`
ID *int `json:"id" db:"id"`
ILOIPAddress *string `json:"iloIpAddress" db:"ilo_ip_address"`
ILOIPGateway *string `json:"iloIpGateway" db:"ilo_ip_gateway"`
ILOIPNetmask *string `json:"iloIpNetmask" db:"ilo_ip_netmask"`
ILOPassword *string `json:"iloPassword" db:"ilo_password"`
ILOUsername *string `json:"iloUsername" db:"ilo_username"`
MgmtIPAddress *string `json:"mgmtIpAddress" db:"mgmt_ip_address"`
MgmtIPGateway *string `json:"mgmtIpGateway" db:"mgmt_ip_gateway"`
MgmtIPNetmask *string `json:"mgmtIpNetmask" db:"mgmt_ip_netmask"`
OfflineReason *string `json:"offlineReason" db:"offline_reason"`
PhysLocation *string `json:"physLocation" db:"phys_location"`
ProfileNames []string `json:"profileNames" db:"profile_name"`
Rack *string `json:"rack" db:"rack"`
Status *string `json:"status" db:"status"`
TCPPort *int `json:"tcpPort" db:"tcp_port"`
Type string `json:"type" db:"server_type"`
XMPPID *string `json:"xmppId" db:"xmpp_id"`
XMPPPasswd *string `json:"xmppPasswd" db:"xmpp_passwd"`
ServerInterfaces []ServerInterfaceInfoV40 `json:"interfaces"`
}
// ServersV1DetailResponse is the JSON object returned for a single server for v1.
type ServersV1DetailResponse struct {
Response []ServerDetailV11 `json:"response"`
Alerts
}
// ServersV3DetailResponse is the JSON object returned for a single server for v3.
type ServersV3DetailResponse struct {
Response []ServerDetailV30 `json:"response"`
Alerts
}
// ServersV4DetailResponse is the JSON object returned for a single server for v4.
type ServersV4DetailResponse struct {
Response []ServerDetailV40 `json:"response"`
Alerts
}
// ServerIPAddress is the data associated with a server's interface's IP address.
type ServerIPAddress struct {
Address string `json:"address" db:"address"`
Gateway *string `json:"gateway" db:"gateway"`
ServiceAddress bool `json:"serviceAddress" db:"service_address"`
}
// ServerInterfaceInfo is the data associated with a server's interface.
type ServerInterfaceInfo struct {
IPAddresses []ServerIPAddress `json:"ipAddresses" db:"ip_addresses"`
MaxBandwidth *uint64 `json:"maxBandwidth" db:"max_bandwidth"`
Monitor bool `json:"monitor" db:"monitor"`
MTU *uint64 `json:"mtu" db:"mtu"`
Name string `json:"name" db:"name"`
}
// ServerInterfaceInfoV40 is the data associated with a V40 server's interface.
type ServerInterfaceInfoV40 struct {
ServerInterfaceInfo
RouterHostName string `json:"routerHostName" db:"router_host_name"`
RouterPortName string `json:"routerPortName" db:"router_port_name"`
}
// GetDefaultAddressOrCIDR returns the IPv4 and IPv6 service addresses of the interface.
func (i *ServerInterfaceInfo) GetDefaultAddress() (string, string) {
ipv4, ipv6 := i.GetDefaultAddressOrCIDR()
address, _, err := net.ParseCIDR(ipv4)
if address != nil && err == nil {
ipv4 = address.String()
}
address, _, err = net.ParseCIDR(ipv6)
if address != nil && err == nil {
ipv6 = address.String()
}
return ipv4, ipv6
}
// GetDefaultAddressOrCIDR returns the IPv4 and IPv6 service addresses of the interface,
// including a subnet, if one exists.
func (i *ServerInterfaceInfo) GetDefaultAddressOrCIDR() (string, string) {
var ipv4, ipv6 string
var err error
for _, ip := range i.IPAddresses {
if ip.ServiceAddress {
address := net.ParseIP(ip.Address)
if address == nil {
address, _, err = net.ParseCIDR(ip.Address)
if err != nil || address == nil {
continue
}
}
if address.To4() != nil {
ipv4 = ip.Address
} else if address.To16() != nil {
ipv6 = ip.Address
}
if ipv4 != "" && ipv6 != "" {
break
}
}
}
return ipv4, ipv6
}
// Value implements the driver.Valuer interface
// marshals struct to json to pass back as a json.RawMessage.
func (sii *ServerInterfaceInfo) Value() (driver.Value, error) {
b, err := json.Marshal(sii)
return b, err
}
// Scan implements the sql.Scanner interface.
//
// This expects src to be a json.RawMessage and unmarshals it into the
// ServerInterfaceInfo.
func (sii *ServerInterfaceInfo) Scan(src interface{}) error {
b, ok := src.([]byte)
if !ok {
return fmt.Errorf("expected deliveryservice in byte array form; got %T", src)
}
return json.Unmarshal([]byte(b), sii)
}
// LegacyInterfaceDetails is the details for interfaces on servers for API v2.
//
// Deprecated: Traffic Ops API version 2 is deprecated, upgrade to Server
// representations that support interfaces (i.e. ServerInterfaceInfoV40
// slices).
type LegacyInterfaceDetails struct {
InterfaceMtu *int `json:"interfaceMtu" db:"interface_mtu"`
InterfaceName *string `json:"interfaceName" db:"interface_name"`
IP6Address *string `json:"ip6Address" db:"ip6_address"`
IP6Gateway *string `json:"ip6Gateway" db:"ip6_gateway"`
IPAddress *string `json:"ipAddress" db:"ip_address"`
IPGateway *string `json:"ipGateway" db:"ip_gateway"`
IPNetmask *string `json:"ipNetmask" db:"ip_netmask"`
}
// ToInterfaces converts a LegacyInterfaceDetails to a slice of
// ServerInterfaceInfo structures. Only one interface is expected and will be marked for monitoring.
// It will generate service addresses according to the passed indicators
// for each address family.
//
// Deprecated: LegacyInterfaceDetails is deprecated, and this will be removed
// with it.
func (lid *LegacyInterfaceDetails) ToInterfaces(ipv4IsService, ipv6IsService bool) ([]ServerInterfaceInfo, error) {
var iface ServerInterfaceInfo
if lid.InterfaceMtu == nil {
return nil, errors.New("interfaceMtu is null")
}
mtu := uint64(*lid.InterfaceMtu)
iface.MTU = &mtu
if lid.InterfaceName == nil {
return nil, errors.New("interfaceName is null")
}
iface.Name = *lid.InterfaceName
// default to true since there should only be one interface from legacy API versions
// if Monitor is false on all interfaces, then TM will see the server as unhealthy
iface.Monitor = true
var ips []ServerIPAddress
if lid.IPAddress != nil && *lid.IPAddress != "" {
if lid.IPGateway != nil && *lid.IPGateway == "" {
lid.IPGateway = nil
}
ipStr := *lid.IPAddress
if lid.IPNetmask != nil && *lid.IPNetmask != "" {
mask := net.ParseIP(*lid.IPNetmask).To4()
if mask == nil {
return nil, fmt.Errorf("Failed to parse netmask '%s'", *lid.IPNetmask)
}
cidr, _ := net.IPv4Mask(mask[0], mask[1], mask[2], mask[3]).Size()
ipStr = fmt.Sprintf("%s/%d", ipStr, cidr)
}
ips = append(ips, ServerIPAddress{
Address: ipStr,
Gateway: lid.IPGateway,
ServiceAddress: ipv4IsService,
})
}
if lid.IP6Address != nil && *lid.IP6Address != "" {
if lid.IP6Gateway != nil && *lid.IP6Gateway == "" {
lid.IP6Gateway = nil
}
ips = append(ips, ServerIPAddress{
Address: *lid.IP6Address,
Gateway: lid.IP6Gateway,
ServiceAddress: ipv6IsService,
})
}
iface.IPAddresses = ips
return []ServerInterfaceInfo{iface}, nil
}
// ToInterfacesV4 upgrades server interfaces from their APIv3 representation to
// an APIv4 representation.
//
// The passed routerName and routerPort can be nil, which will leave the
// upgradeded interfaces' RouterHostName and RouterPortName unset, or they can
// be pointers to string values to which ALL of the interfaces will have their
// RouterHostName and RouterPortName set.
func ToInterfacesV4(oldInterfaces []ServerInterfaceInfo, routerName, routerPort *string) ([]ServerInterfaceInfoV40, error) {
v4Interfaces := make([]ServerInterfaceInfoV40, 0)
var v4Int ServerInterfaceInfoV40
for _, i := range oldInterfaces {
v4Int.ServerInterfaceInfo = i
if routerName != nil {
v4Int.RouterHostName = *routerName
}
if routerPort != nil {
v4Int.RouterPortName = *routerPort
}
v4Interfaces = append(v4Interfaces, v4Int)
}
return v4Interfaces, nil
}
// ToInterfacesV4 converts a LegacyInterfaceDetails to a slice of
// ServerInterfaceInfoV40 structures.
//
// Only one interface is expected and will be marked for monitoring. This will
// generate service addresses according to the passed indicators for each
// address family.
//
// The passed routerName and routerPort can be nil, which will leave the
// upgradeded interfaces' RouterHostName and RouterPortName unset, or they can
// be pointers to string values to which ALL of the interfaces will have their
// RouterHostName and RouterPortName set.
//
// Deprecated: LegacyInterfaceDetails is deprecated, and this will be removed
// with it.
func (lid *LegacyInterfaceDetails) ToInterfacesV4(ipv4IsService, ipv6IsService bool, routerName, routerPort *string) ([]ServerInterfaceInfoV40, error) {
var iface ServerInterfaceInfoV40
if lid.InterfaceMtu == nil {
return nil, errors.New("interfaceMtu is null")
}
mtu := uint64(*lid.InterfaceMtu)
iface.MTU = &mtu
if lid.InterfaceName == nil {
return nil, errors.New("interfaceName is null")
}
iface.Name = *lid.InterfaceName
// default to true since there should only be one interface from legacy API versions
// if Monitor is false on all interfaces, then TM will see the server as unhealthy
iface.Monitor = true
var ips []ServerIPAddress
if lid.IPAddress != nil && *lid.IPAddress != "" {
if lid.IPGateway != nil && *lid.IPGateway == "" {
lid.IPGateway = nil
}
ipStr := *lid.IPAddress
if lid.IPNetmask != nil && *lid.IPNetmask != "" {
mask := net.ParseIP(*lid.IPNetmask).To4()
if mask == nil {
return nil, fmt.Errorf("Failed to parse netmask '%s'", *lid.IPNetmask)
}
cidr, _ := net.IPv4Mask(mask[0], mask[1], mask[2], mask[3]).Size()
ipStr = fmt.Sprintf("%s/%d", ipStr, cidr)
}
ips = append(ips, ServerIPAddress{
Address: ipStr,
Gateway: lid.IPGateway,
ServiceAddress: ipv4IsService,
})
}
if lid.IP6Address != nil && *lid.IP6Address != "" {
if lid.IP6Gateway != nil && *lid.IP6Gateway == "" {
lid.IP6Gateway = nil
}
ips = append(ips, ServerIPAddress{
Address: *lid.IP6Address,
Gateway: lid.IP6Gateway,
ServiceAddress: ipv6IsService,
})
}
iface.IPAddresses = ips
if routerName != nil {
iface.RouterHostName = *routerName
}
if routerPort != nil {
iface.RouterPortName = *routerPort
}
return []ServerInterfaceInfoV40{iface}, nil
}
// String implements the fmt.Stringer interface.
func (lid LegacyInterfaceDetails) String() string {
var b strings.Builder
b.Write([]byte("LegacyInterfaceDetails(InterfaceMtu="))
if lid.InterfaceMtu == nil {
b.Write([]byte("nil"))
} else {
b.WriteString(strconv.FormatInt(int64(*lid.InterfaceMtu), 10))
}
b.Write([]byte(", InterfaceName="))
if lid.InterfaceName != nil {
b.WriteRune('\'')
b.WriteString(*lid.InterfaceName)
b.WriteRune('\'')
} else {
b.Write([]byte("nil"))
}
b.Write([]byte(", IP6Address="))
if lid.IP6Address != nil {
b.WriteRune('\'')
b.WriteString(*lid.IP6Address)
b.WriteRune('\'')
} else {
b.Write([]byte("nil"))
}
b.Write([]byte(", IP6Gateway="))
if lid.IP6Gateway != nil {
b.WriteRune('\'')
b.WriteString(*lid.IP6Gateway)
b.WriteRune('\'')
} else {
b.Write([]byte("nil"))
}
b.Write([]byte(", IPAddress="))
if lid.IPAddress != nil {
b.WriteRune('\'')
b.WriteString(*lid.IPAddress)
b.WriteRune('\'')
} else {
b.Write([]byte("nil"))
}
b.Write([]byte(", IPGateway="))
if lid.IPGateway != nil {
b.WriteRune('\'')
b.WriteString(*lid.IPGateway)
b.WriteRune('\'')
} else {
b.Write([]byte("nil"))
}
b.Write([]byte(", IPNetmask="))
if lid.IPNetmask != nil {
b.WriteRune('\'')
b.WriteString(*lid.IPNetmask)
b.WriteRune('\'')
} else {
b.Write([]byte("nil"))
}
b.WriteRune(')')
return b.String()
}
// V4InterfaceInfoToV3Interfaces downgrades a set of ServerInterfaceInfoV40s to
// ServerInterfaceInfos.
func V4InterfaceInfoToV3Interfaces(serverInterfaces []ServerInterfaceInfoV40) ([]ServerInterfaceInfo, error) {
var interfaces []ServerInterfaceInfo
for _, intFace := range serverInterfaces {
var interfaceV3 ServerInterfaceInfo
interfaceV3.IPAddresses = intFace.IPAddresses
interfaceV3.Monitor = intFace.Monitor
interfaceV3.MaxBandwidth = intFace.MaxBandwidth
interfaceV3.MTU = intFace.MTU
interfaceV3.Name = intFace.Name
interfaces = append(interfaces, interfaceV3)
}
return interfaces, nil
}
// V4InterfaceInfoToLegacyInterfaces downgrades a set of
// ServerInterfaceInfoV40s to a LegacyInterfaceDetails.
//
// Deprecated: LegacyInterfaceDetails is deprecated, and this will be removed
// with it.
func V4InterfaceInfoToLegacyInterfaces(serverInterfaces []ServerInterfaceInfoV40) (LegacyInterfaceDetails, error) {
var legacyDetails LegacyInterfaceDetails
for _, intFace := range serverInterfaces {
foundServiceInterface := false
for _, addr := range intFace.IPAddresses {
if !addr.ServiceAddress {
continue
}
foundServiceInterface = true
address := addr.Address
gateway := addr.Gateway
var parsedIp net.IP
var mask *net.IPNet
var err error
parsedIp, mask, err = net.ParseCIDR(address)
if err != nil {
parsedIp = net.ParseIP(address)
if parsedIp == nil {
return legacyDetails, fmt.Errorf("Failed to parse '%s' as network or CIDR string: %v", address, err)
}
}
if parsedIp.To4() == nil {
legacyDetails.IP6Address = &address
legacyDetails.IP6Gateway = gateway
} else if mask != nil {
legacyDetails.IPAddress = util.StrPtr(parsedIp.String())
legacyDetails.IPGateway = gateway
legacyDetails.IPNetmask = util.StrPtr(fmt.Sprintf("%d.%d.%d.%d", mask.Mask[0], mask.Mask[1], mask.Mask[2], mask.Mask[3]))
} else {
legacyDetails.IPAddress = util.StrPtr(parsedIp.String())
legacyDetails.IPGateway = gateway
legacyDetails.IPNetmask = new(string)
}
if intFace.MTU != nil {
legacyDetails.InterfaceMtu = util.IntPtr(int(*intFace.MTU))
}
// This should no longer matter now that short-circuiting is better,
// but this temporary variable is necessary because the 'intFace'
// variable is referential, so taking '&intFace.Name' would cause
// problems when intFace is reassigned.
name := intFace.Name
legacyDetails.InterfaceName = &name
// we can jump out here since servers can only legally have one
// IPv4 and one IPv6 service address
if legacyDetails.IPAddress != nil && *legacyDetails.IPAddress != "" && legacyDetails.IP6Address != nil && *legacyDetails.IP6Address != "" {
break
}
}
if foundServiceInterface {
return legacyDetails, nil
}
}
return legacyDetails, errors.New("no service addresses found")
}
// InterfaceInfoToLegacyInterfaces converts a ServerInterfaceInfo to an
// equivalent LegacyInterfaceDetails structure. It does this by creating the
// IP address fields using the "service" interface's IP addresses. All others
// are discarded, as the legacy format is incapable of representing them.
//
// Deprecated: LegacyInterfaceDetails is deprecated, and this will be removed
// with it.
func InterfaceInfoToLegacyInterfaces(serverInterfaces []ServerInterfaceInfo) (LegacyInterfaceDetails, error) {
var legacyDetails LegacyInterfaceDetails
for _, intFace := range serverInterfaces {
foundServiceInterface := false
for _, addr := range intFace.IPAddresses {
if !addr.ServiceAddress {
continue
}
foundServiceInterface = true
address := addr.Address
gateway := addr.Gateway
var parsedIp net.IP
var mask *net.IPNet
var err error
parsedIp, mask, err = net.ParseCIDR(address)
if err != nil {
parsedIp = net.ParseIP(address)
if parsedIp == nil {
return legacyDetails, fmt.Errorf("Failed to parse '%s' as network or CIDR string: %v", address, err)
}
}
if parsedIp.To4() == nil {
legacyDetails.IP6Address = &address
legacyDetails.IP6Gateway = gateway
} else if mask != nil {
legacyDetails.IPAddress = util.StrPtr(parsedIp.String())
legacyDetails.IPGateway = gateway
legacyDetails.IPNetmask = util.StrPtr(fmt.Sprintf("%d.%d.%d.%d", mask.Mask[0], mask.Mask[1], mask.Mask[2], mask.Mask[3]))
} else {
legacyDetails.IPAddress = util.StrPtr(parsedIp.String())
legacyDetails.IPGateway = gateway
legacyDetails.IPNetmask = new(string)
}
if intFace.MTU != nil {
legacyDetails.InterfaceMtu = util.IntPtr(int(*intFace.MTU))
}
// This should no longer matter now that short-circuiting is better,
// but this temporary variable is necessary because the 'intFace'
// variable is referential, so taking '&intFace.Name' would cause
// problems when intFace is reassigned.
name := intFace.Name
legacyDetails.InterfaceName = &name
// we can jump out here since servers can only legally have one
// IPv4 and one IPv6 service address
if legacyDetails.IPAddress != nil && *legacyDetails.IPAddress != "" && legacyDetails.IP6Address != nil && *legacyDetails.IP6Address != "" {
break
}
}
if foundServiceInterface {
return legacyDetails, nil
}
}
return legacyDetails, errors.New("no service addresses found")
}
// Server is a non-"nullable" representation of a Server as it appeared in API
// version 2.0
//
// Deprecated: Please use versioned and nullable structures from now on.
type Server struct {
Cachegroup string `json:"cachegroup" db:"cachegroup"`
CachegroupID int `json:"cachegroupId" db:"cachegroup_id"`
CDNID int `json:"cdnId" db:"cdn_id"`
CDNName string `json:"cdnName" db:"cdn_name"`
DeliveryServices map[string][]string `json:"deliveryServices,omitempty"`
DomainName string `json:"domainName" db:"domain_name"`
FQDN *string `json:"fqdn,omitempty"`
FqdnTime time.Time `json:"-"`
GUID string `json:"guid" db:"guid"`
HostName string `json:"hostName" db:"host_name"`
HTTPSPort int `json:"httpsPort" db:"https_port"`
ID int `json:"id" db:"id"`
ILOIPAddress string `json:"iloIpAddress" db:"ilo_ip_address"`
ILOIPGateway string `json:"iloIpGateway" db:"ilo_ip_gateway"`
ILOIPNetmask string `json:"iloIpNetmask" db:"ilo_ip_netmask"`
ILOPassword string `json:"iloPassword" db:"ilo_password"`
ILOUsername string `json:"iloUsername" db:"ilo_username"`
InterfaceMtu int `json:"interfaceMtu" db:"interface_mtu"`
InterfaceName string `json:"interfaceName" db:"interface_name"`
IP6Address string `json:"ip6Address" db:"ip6_address"`
IP6IsService bool `json:"ip6IsService" db:"ip6_address_is_service"`
IP6Gateway string `json:"ip6Gateway" db:"ip6_gateway"`
IPAddress string `json:"ipAddress" db:"ip_address"`
IPIsService bool `json:"ipIsService" db:"ip_address_is_service"`
IPGateway string `json:"ipGateway" db:"ip_gateway"`
IPNetmask string `json:"ipNetmask" db:"ip_netmask"`
LastUpdated TimeNoMod `json:"lastUpdated" db:"last_updated"`
MgmtIPAddress string `json:"mgmtIpAddress" db:"mgmt_ip_address"`
MgmtIPGateway string `json:"mgmtIpGateway" db:"mgmt_ip_gateway"`
MgmtIPNetmask string `json:"mgmtIpNetmask" db:"mgmt_ip_netmask"`
OfflineReason string `json:"offlineReason" db:"offline_reason"`
PhysLocation string `json:"physLocation" db:"phys_location"`
PhysLocationID int `json:"physLocationId" db:"phys_location_id"`
Profile string `json:"profile" db:"profile"`
ProfileDesc string `json:"profileDesc" db:"profile_desc"`
ProfileID int `json:"profileId" db:"profile_id"`
Rack string `json:"rack" db:"rack"`
RevalPending bool `json:"revalPending" db:"reval_pending"`
RouterHostName string `json:"routerHostName" db:"router_host_name"`
RouterPortName string `json:"routerPortName" db:"router_port_name"`
Status string `json:"status" db:"status"`
StatusID int `json:"statusId" db:"status_id"`
TCPPort int `json:"tcpPort" db:"tcp_port"`
Type string `json:"type" db:"server_type"`
TypeID int `json:"typeId" db:"server_type_id"`
UpdPending bool `json:"updPending" db:"upd_pending"`
XMPPID string `json:"xmppId" db:"xmpp_id"`
XMPPPasswd string `json:"xmppPasswd" db:"xmpp_passwd"`
}
// CommonServerProperties is just the collection of properties which are
// shared by all servers across API versions.
type CommonServerProperties struct {
Cachegroup *string `json:"cachegroup" db:"cachegroup"`
CachegroupID *int `json:"cachegroupId" db:"cachegroup_id"`
CDNID *int `json:"cdnId" db:"cdn_id"`
CDNName *string `json:"cdnName" db:"cdn_name"`
DeliveryServices *map[string][]string `json:"deliveryServices,omitempty"`
DomainName *string `json:"domainName" db:"domain_name"`
FQDN *string `json:"fqdn,omitempty"`
FqdnTime time.Time `json:"-"`
GUID *string `json:"guid" db:"guid"`
HostName *string `json:"hostName" db:"host_name"`
HTTPSPort *int `json:"httpsPort" db:"https_port"`
ID *int `json:"id" db:"id"`
ILOIPAddress *string `json:"iloIpAddress" db:"ilo_ip_address"`
ILOIPGateway *string `json:"iloIpGateway" db:"ilo_ip_gateway"`
ILOIPNetmask *string `json:"iloIpNetmask" db:"ilo_ip_netmask"`
ILOPassword *string `json:"iloPassword" db:"ilo_password"`
ILOUsername *string `json:"iloUsername" db:"ilo_username"`
LastUpdated *TimeNoMod `json:"lastUpdated" db:"last_updated"`
MgmtIPAddress *string `json:"mgmtIpAddress" db:"mgmt_ip_address"`
MgmtIPGateway *string `json:"mgmtIpGateway" db:"mgmt_ip_gateway"`
MgmtIPNetmask *string `json:"mgmtIpNetmask" db:"mgmt_ip_netmask"`
OfflineReason *string `json:"offlineReason" db:"offline_reason"`
PhysLocation *string `json:"physLocation" db:"phys_location"`
PhysLocationID *int `json:"physLocationId" db:"phys_location_id"`
Profile *string `json:"profile" db:"profile"`
ProfileDesc *string `json:"profileDesc" db:"profile_desc"`
ProfileID *int `json:"profileId" db:"profile_id"`
Rack *string `json:"rack" db:"rack"`
RevalPending *bool `json:"revalPending" db:"reval_pending"`
Status *string `json:"status" db:"status"`
StatusID *int `json:"statusId" db:"status_id"`
TCPPort *int `json:"tcpPort" db:"tcp_port"`
Type string `json:"type" db:"server_type"`
TypeID *int `json:"typeId" db:"server_type_id"`
UpdPending *bool `json:"updPending" db:"upd_pending"`
XMPPID *string `json:"xmppId" db:"xmpp_id"`
XMPPPasswd *string `json:"xmppPasswd" db:"xmpp_passwd"`
}
// ServerNullableV11 is a server as it appeared in API version 1.1.
type ServerNullableV11 struct {
LegacyInterfaceDetails
CommonServerProperties
RouterHostName *string `json:"routerHostName" db:"router_host_name"`
RouterPortName *string `json:"routerPortName" db:"router_port_name"`
}
// ServerNullableV2 is a server as it appeared in API v2.
//
// Deprecated: Traffic Ops API version 2 is deprecated, new code should use
// ServerV40 or newer structures.
type ServerNullableV2 struct {
ServerNullableV11
IPIsService *bool `json:"ipIsService" db:"ip_address_is_service"`
IP6IsService *bool `json:"ip6IsService" db:"ip6_address_is_service"`
}
// ToNullable converts the Server to an equivalent, "nullable" structure.
//
// Note that "zero" values (e.g. the empty string "") are NOT coerced to actual
// null values. In particular, the only fields that will possibly be nil are
// FQDN - if the original server had a nil FQDN - and DeliveryServices - which
// will actually be a pointer to a nil map if the original server had a nil
// DeliveryServices map.
// Further note that this makes "shallow" copies of member properties; if
// reference types (map, slice, pointer etc.) are altered on the original after
// conversion, the changes WILL affect the nullable copy.
//
// Deprecated: Traffic Ops API version 2 is deprecated, new code should use
// ServerV40 or newer structures.
func (s Server) ToNullable() ServerNullableV2 {
return ServerNullableV2{
ServerNullableV11: ServerNullableV11{
CommonServerProperties: CommonServerProperties{
Cachegroup: &s.Cachegroup,
CachegroupID: &s.CachegroupID,
CDNID: &s.CDNID,
CDNName: &s.CDNName,
DeliveryServices: &s.DeliveryServices,
DomainName: &s.DomainName,
FQDN: s.FQDN,
FqdnTime: s.FqdnTime,
GUID: &s.GUID,
HostName: &s.HostName,
HTTPSPort: &s.HTTPSPort,
ID: &s.ID,
ILOIPAddress: &s.ILOIPAddress,
ILOIPGateway: &s.ILOIPGateway,
ILOIPNetmask: &s.ILOIPNetmask,
ILOPassword: &s.ILOPassword,
ILOUsername: &s.ILOUsername,
LastUpdated: &s.LastUpdated,
MgmtIPAddress: &s.MgmtIPAddress,
MgmtIPGateway: &s.MgmtIPGateway,
MgmtIPNetmask: &s.MgmtIPNetmask,
OfflineReason: &s.OfflineReason,
PhysLocation: &s.PhysLocation,
PhysLocationID: &s.PhysLocationID,
Profile: &s.Profile,
ProfileDesc: &s.ProfileDesc,
ProfileID: &s.ProfileID,
Rack: &s.Rack,
RevalPending: &s.RevalPending,
Status: &s.Status,
StatusID: &s.StatusID,
TCPPort: &s.TCPPort,
Type: s.Type,
TypeID: &s.TypeID,
UpdPending: &s.UpdPending,
XMPPID: &s.XMPPID,
XMPPPasswd: &s.XMPPPasswd,
},
LegacyInterfaceDetails: LegacyInterfaceDetails{
InterfaceMtu: &s.InterfaceMtu,
InterfaceName: &s.InterfaceName,
IPAddress: &s.IPAddress,
IPGateway: &s.IPGateway,
IPNetmask: &s.IPNetmask,
IP6Address: &s.IP6Address,
IP6Gateway: &s.IP6Gateway,
},
RouterHostName: &s.RouterHostName,
RouterPortName: &s.RouterPortName,
},
IPIsService: &s.IPIsService,
IP6IsService: &s.IP6IsService,
}
}
func coerceBool(b *bool) bool {
if b == nil {
return false
}
return *b
}
func coerceInt(i *int) int {
if i == nil {
return 0
}
return *i
}
func coerceString(s *string) string {
if s == nil {
return ""
}
return *s
}
// ToNonNullable converts the ServerNullableV2 safely to a Server structure.
//
// Deprecated: Traffic Ops API version 2 is deprecated, new code should use
// ServerV40 or newer structures.
func (s ServerNullableV2) ToNonNullable() Server {
ret := Server{
Cachegroup: coerceString(s.Cachegroup),
CachegroupID: coerceInt(s.CachegroupID),
CDNID: coerceInt((s.CDNID)),
CDNName: coerceString(s.CDNName),
DomainName: coerceString(s.DomainName),
FQDN: s.FQDN,
FqdnTime: s.FqdnTime,
GUID: coerceString(s.GUID),
HostName: coerceString(s.HostName),
HTTPSPort: coerceInt(s.HTTPSPort),
ID: coerceInt(s.ID),
ILOIPAddress: coerceString(s.ILOIPAddress),
ILOIPGateway: coerceString(s.ILOIPGateway),
ILOIPNetmask: coerceString(s.ILOIPNetmask),
ILOPassword: coerceString(s.ILOPassword),
ILOUsername: coerceString(s.ILOUsername),
InterfaceMtu: coerceInt(s.InterfaceMtu),
InterfaceName: coerceString(s.InterfaceName),
IP6Address: coerceString(s.IP6Address),
IP6IsService: coerceBool(s.IP6IsService),
IP6Gateway: coerceString(s.IP6Gateway),
IPAddress: coerceString(s.IPAddress),
IPIsService: coerceBool(s.IPIsService),
IPGateway: coerceString(s.IPGateway),
IPNetmask: coerceString(s.IPNetmask),
MgmtIPAddress: coerceString(s.MgmtIPAddress),
MgmtIPGateway: coerceString(s.MgmtIPGateway),
MgmtIPNetmask: coerceString(s.MgmtIPNetmask),
OfflineReason: coerceString(s.OfflineReason),
PhysLocation: coerceString(s.PhysLocation),
PhysLocationID: coerceInt(s.PhysLocationID),
Profile: coerceString(s.Profile),
ProfileDesc: coerceString(s.ProfileDesc),
ProfileID: coerceInt(s.ProfileID),
Rack: coerceString(s.Rack),
RevalPending: coerceBool(s.RevalPending),
RouterHostName: coerceString(s.RouterHostName),
RouterPortName: coerceString(s.RouterPortName),
Status: coerceString(s.Status),
StatusID: coerceInt(s.StatusID),
TCPPort: coerceInt(s.TCPPort),
Type: s.Type,
TypeID: coerceInt(s.TypeID),
UpdPending: coerceBool(s.UpdPending),
XMPPID: coerceString(s.XMPPID),
XMPPPasswd: coerceString(s.XMPPPasswd),
}
if s.DeliveryServices == nil {
ret.DeliveryServices = nil
} else {
ret.DeliveryServices = *s.DeliveryServices
}
if s.LastUpdated == nil {
ret.LastUpdated = TimeNoMod{}
} else {
ret.LastUpdated = *s.LastUpdated
}
return ret
}
// Upgrade upgrades the ServerNullableV2 to the new ServerNullable structure.
//
// Note that this makes "shallow" copies of all underlying data, so changes to
// the original will affect the upgraded copy.
//
// Deprecated: Traffic Ops API versions 2 and 3 are both deprecated, new code
// should use ServerV40 or newer structures.
func (s ServerNullableV2) Upgrade() (ServerV30, error) {
ipv4IsService := false
if s.IPIsService != nil {
ipv4IsService = *s.IPIsService
}
ipv6IsService := false
if s.IP6IsService != nil {
ipv6IsService = *s.IP6IsService
}
upgraded := ServerV30{
CommonServerProperties: s.CommonServerProperties,
RouterHostName: s.RouterHostName,
RouterPortName: s.RouterPortName,
}
infs, err := s.LegacyInterfaceDetails.ToInterfaces(ipv4IsService, ipv6IsService)
if err != nil {
return upgraded, err
}
upgraded.Interfaces = infs
return upgraded, nil
}
// UpgradeToV40 upgrades the ServerV30 to a ServerV40.
//
// This makes a "shallow" copy of the structure's properties.
//
// Deprecated: Traffic Ops API version 3 is deprecated, new code should use
// ServerV40 or newer structures.
func (s ServerV30) UpgradeToV40(profileNames []string) (ServerV40, error) {
upgraded := UpdateServerPropertiesV40(profileNames, s.CommonServerProperties)
upgraded.StatusLastUpdated = s.StatusLastUpdated
infs, err := ToInterfacesV4(s.Interfaces, s.RouterHostName, s.RouterPortName)
if err != nil {
return upgraded, err
}
upgraded.Interfaces = infs
return upgraded, nil
}
// UpgradeToV40 upgrades the ServerNullableV2 to a ServerV40.
//
// This makes a "shallow" copy of the structure's properties.
//
// Deprecated: Traffic Ops API version 2 is deprecated, new code should use
// ServerV40 or newer structures.
func (s ServerNullableV2) UpgradeToV40(profileNames []string) (ServerV40, error) {
ipv4IsService := false
if s.IPIsService != nil {
ipv4IsService = *s.IPIsService
}
ipv6IsService := false
if s.IP6IsService != nil {
ipv6IsService = *s.IP6IsService
}
upgraded := UpdateServerPropertiesV40(profileNames, s.CommonServerProperties)
infs, err := s.LegacyInterfaceDetails.ToInterfacesV4(ipv4IsService, ipv6IsService, s.RouterHostName, s.RouterPortName)
if err != nil {
return upgraded, err
}
upgraded.Interfaces = infs
return upgraded, nil
}
// UpdateServerPropertiesV40 updates CommonServerProperties of V2 and V3 to ServerV40
func UpdateServerPropertiesV40(profileNames []string, properties CommonServerProperties) ServerV40 {
return ServerV40{
Cachegroup: properties.Cachegroup,
CachegroupID: properties.CachegroupID,
CDNID: properties.CDNID,
CDNName: properties.CDNName,
DeliveryServices: properties.DeliveryServices,
DomainName: properties.DomainName,
FQDN: properties.FQDN,
FqdnTime: properties.FqdnTime,
GUID: properties.GUID,
HostName: properties.HostName,
HTTPSPort: properties.HTTPSPort,
ID: properties.ID,
ILOIPAddress: properties.ILOIPAddress,
ILOIPGateway: properties.ILOIPGateway,
ILOIPNetmask: properties.ILOIPNetmask,
ILOPassword: properties.ILOPassword,
ILOUsername: properties.ILOUsername,
LastUpdated: properties.LastUpdated,
MgmtIPAddress: properties.MgmtIPAddress,
MgmtIPGateway: properties.MgmtIPGateway,
MgmtIPNetmask: properties.MgmtIPNetmask,
OfflineReason: properties.OfflineReason,
ProfileNames: profileNames,
PhysLocation: properties.PhysLocation,
PhysLocationID: properties.PhysLocationID,
Rack: properties.Rack,
RevalPending: properties.RevalPending,
Status: properties.Status,
StatusID: properties.StatusID,
TCPPort: properties.TCPPort,
Type: properties.Type,
TypeID: properties.TypeID,
UpdPending: properties.UpdPending,
XMPPID: properties.XMPPID,
XMPPPasswd: properties.XMPPPasswd,
}
}
// ServerV40 is the representation of a Server in version 4.0 of the Traffic Ops API.
type ServerV40 struct {
Cachegroup *string `json:"cachegroup" db:"cachegroup"`
CachegroupID *int `json:"cachegroupId" db:"cachegroup_id"`
CDNID *int `json:"cdnId" db:"cdn_id"`
CDNName *string `json:"cdnName" db:"cdn_name"`
DeliveryServices *map[string][]string `json:"deliveryServices,omitempty"`
DomainName *string `json:"domainName" db:"domain_name"`
FQDN *string `json:"fqdn,omitempty"`
FqdnTime time.Time `json:"-"`
GUID *string `json:"guid" db:"guid"`
HostName *string `json:"hostName" db:"host_name"`
HTTPSPort *int `json:"httpsPort" db:"https_port"`
ID *int `json:"id" db:"id"`
ILOIPAddress *string `json:"iloIpAddress" db:"ilo_ip_address"`
ILOIPGateway *string `json:"iloIpGateway" db:"ilo_ip_gateway"`
ILOIPNetmask *string `json:"iloIpNetmask" db:"ilo_ip_netmask"`
ILOPassword *string `json:"iloPassword" db:"ilo_password"`
ILOUsername *string `json:"iloUsername" db:"ilo_username"`
LastUpdated *TimeNoMod `json:"lastUpdated" db:"last_updated"`
MgmtIPAddress *string `json:"mgmtIpAddress" db:"mgmt_ip_address"`
MgmtIPGateway *string `json:"mgmtIpGateway" db:"mgmt_ip_gateway"`
MgmtIPNetmask *string `json:"mgmtIpNetmask" db:"mgmt_ip_netmask"`
OfflineReason *string `json:"offlineReason" db:"offline_reason"`
PhysLocation *string `json:"physLocation" db:"phys_location"`
PhysLocationID *int `json:"physLocationId" db:"phys_location_id"`
ProfileNames []string `json:"profileNames" db:"profile_name"`
Rack *string `json:"rack" db:"rack"`
RevalPending *bool `json:"revalPending" db:"reval_pending"`
Status *string `json:"status" db:"status"`
StatusID *int `json:"statusId" db:"status_id"`
TCPPort *int `json:"tcpPort" db:"tcp_port"`
Type string `json:"type" db:"server_type"`
TypeID *int `json:"typeId" db:"server_type_id"`
UpdPending *bool `json:"updPending" db:"upd_pending"`
XMPPID *string `json:"xmppId" db:"xmpp_id"`
XMPPPasswd *string `json:"xmppPasswd" db:"xmpp_passwd"`
Interfaces []ServerInterfaceInfoV40 `json:"interfaces" db:"interfaces"`
StatusLastUpdated *time.Time `json:"statusLastUpdated" db:"status_last_updated"`
ConfigUpdateTime *time.Time `json:"configUpdateTime" db:"config_update_time"`
ConfigApplyTime *time.Time `json:"configApplyTime" db:"config_apply_time"`
RevalUpdateTime *time.Time `json:"revalUpdateTime" db:"revalidate_update_time"`
RevalApplyTime *time.Time `json:"revalApplyTime" db:"revalidate_apply_time"`
}
// ServerV4 is the representation of a Server in the latest minor version of
// version 4 of the Traffic Ops API.
type ServerV4 = ServerV40
// ServerV30 is the representation of a Server in version 3 of the Traffic Ops API.
type ServerV30 struct {
CommonServerProperties
RouterHostName *string `json:"routerHostName" db:"router_host_name"`
RouterPortName *string `json:"routerPortName" db:"router_port_name"`
Interfaces []ServerInterfaceInfo `json:"interfaces" db:"interfaces"`
StatusLastUpdated *time.Time `json:"statusLastUpdated" db:"status_last_updated"`
}
// ServerNullable represents an ATC server, as returned by the TO API.
//
// Deprecated: Traffic Ops API version 3 is deprecated, new code should use
// ServerV40 or newer structures.
type ServerNullable ServerV30
// ToServerV2 converts the server to an equivalent ServerNullableV2 structure,
// if possible. If the conversion could not be performed, an error is returned.
func (s *ServerNullable) ToServerV2() (ServerNullableV2, error) {
nullable := ServerV30(*s)
return nullable.ToServerV2()
}
// ToServerV2 converts the server to an equivalent ServerNullableV2 structure,
// if possible. If the conversion could not be performed, an error is returned.
//
// Deprecated: Traffic Ops API version 2 is deprecated, new code should use
// ServerV40 or newer structures.
func (s *ServerV30) ToServerV2() (ServerNullableV2, error) {
legacyServer := ServerNullableV2{
ServerNullableV11: ServerNullableV11{
CommonServerProperties: s.CommonServerProperties,
},
IPIsService: new(bool),
IP6IsService: new(bool),
}
var err error
legacyServer.LegacyInterfaceDetails, err = InterfaceInfoToLegacyInterfaces(s.Interfaces)
if err != nil {
return legacyServer, err
}
*legacyServer.IPIsService = legacyServer.LegacyInterfaceDetails.IPAddress != nil && *legacyServer.LegacyInterfaceDetails.IPAddress != ""
*legacyServer.IP6IsService = legacyServer.LegacyInterfaceDetails.IP6Address != nil && *legacyServer.LegacyInterfaceDetails.IP6Address != ""
return legacyServer, nil
}
// ToServerV3FromV4 downgrades the ServerV40 to a ServerV30.
//
// This makes a "shallow" copy of most of the structure's properties.
//
// Deprecated: Traffic Ops API version 3 is deprecated, new code should use
// ServerV40 or newer structures.
func (s *ServerV40) ToServerV3FromV4(csp CommonServerProperties) (ServerV30, error) {
routerHostName := ""
routerPortName := ""
interfaces := make([]ServerInterfaceInfo, 0)
i := ServerInterfaceInfo{}
for _, in := range s.Interfaces {
i.Name = in.Name
i.MTU = in.MTU
i.MaxBandwidth = in.MaxBandwidth
i.Monitor = in.Monitor
i.IPAddresses = in.IPAddresses
for _, ip := range i.IPAddresses {
if ip.ServiceAddress {
routerHostName = in.RouterHostName
routerPortName = in.RouterPortName
}
}
interfaces = append(interfaces, i)
}
serverV30 := ServerV30{
CommonServerProperties: csp,
Interfaces: interfaces,
StatusLastUpdated: s.StatusLastUpdated,
}
if len(s.Interfaces) != 0 {
serverV30.RouterHostName = &routerHostName
serverV30.RouterPortName = &routerPortName
}
return serverV30, nil
}
// ToServerV2FromV4 downgrades the ServerV40 to a ServerNullableV2.
//
// This makes a "shallow" copy of most of the structure's properties.
//
// Deprecated: Traffic Ops API version 2 is deprecated, new code should use
// ServerV40 or newer structures.
func (s *ServerV40) ToServerV2FromV4(csp CommonServerProperties) (ServerNullableV2, error) {
routerHostName := ""
routerPortName := ""
legacyServer := ServerNullableV2{
ServerNullableV11: ServerNullableV11{
CommonServerProperties: csp,
},
IPIsService: new(bool),
IP6IsService: new(bool),
}
interfaces := make([]ServerInterfaceInfo, 0)
i := ServerInterfaceInfo{}
for _, in := range s.Interfaces {
i.Name = in.Name
i.MTU = in.MTU
i.MaxBandwidth = in.MaxBandwidth
i.Monitor = in.Monitor
i.IPAddresses = in.IPAddresses
for _, ip := range i.IPAddresses {
if ip.ServiceAddress {
routerHostName = in.RouterHostName
routerPortName = in.RouterPortName
}
}
interfaces = append(interfaces, i)
}
var err error
legacyServer.LegacyInterfaceDetails, err = InterfaceInfoToLegacyInterfaces(interfaces)
if err != nil {
return legacyServer, err
}
*legacyServer.IPIsService = legacyServer.LegacyInterfaceDetails.IPAddress != nil && *legacyServer.LegacyInterfaceDetails.IPAddress != ""
*legacyServer.IP6IsService = legacyServer.LegacyInterfaceDetails.IP6Address != nil && *legacyServer.LegacyInterfaceDetails.IP6Address != ""
if len(s.Interfaces) != 0 {
legacyServer.RouterHostName = &routerHostName
legacyServer.RouterPortName = &routerPortName
}
return legacyServer, nil
}
// ServerUpdateStatusV4 is the type of each entry in the `response` property of
// the response from Traffic Ops to GET requests made to its
// /servers/{{host name}}/update_status in the latest minor API
// v4.0 endpoint.
type ServerUpdateStatusV4 ServerUpdateStatusV40
// ServerUpdateStatusV40 is the type of each entry in the `response` property of
// the response from Traffic Ops to GET requests made to its
// /servers/{{host name}}/update_status in API v4.0 endpoint.
type ServerUpdateStatusV40 struct {
HostName string `json:"host_name"`
UpdatePending bool `json:"upd_pending"`
RevalPending bool `json:"reval_pending"`
UseRevalPending bool `json:"use_reval_pending"`
HostId int `json:"host_id"`
Status string `json:"status"`
ParentPending bool `json:"parent_pending"`
ParentRevalPending bool `json:"parent_reval_pending"`
ConfigUpdateTime *time.Time `json:"config_update_time"`
ConfigApplyTime *time.Time `json:"config_apply_time"`
RevalidateUpdateTime *time.Time `json:"revalidate_update_time"`
RevalidateApplyTime *time.Time `json:"revalidate_apply_time"`
}
// Downgrade strips the Config and Revalidate timestamps from
// ServerUpdateStatusV40 to return previous versions of the struct to ensure
// previous compatibility.
func (sus ServerUpdateStatusV40) Downgrade() ServerUpdateStatus {
return ServerUpdateStatus{
HostName: sus.HostName,
UpdatePending: sus.UpdatePending,
RevalPending: sus.RevalPending,
UseRevalPending: sus.UseRevalPending,
HostId: sus.HostId,
Status: sus.Status,
ParentPending: sus.ParentPending,
ParentRevalPending: sus.ParentRevalPending,
}
}
// ServerUpdateStatus is the type of each entry in the `response` property of
// the response from Traffic Ops to GET requests made to its
// /servers/{{host name}}/update_status API endpoint.
//
// This is a subset of Server structure information mainly relating to what
// operations t3c has done/needs to do. For most purposes, using Server
// structures will be better - especially since the basic principle of this
// type is predicated on a lie: that server host names are unique.
//
// Deprecated: ServerUpdateStatus is for use only in APIs below V4. New code
// should use ServerUpdateStatusV40 or newer.
type ServerUpdateStatus struct {
HostName string `json:"host_name"`
UpdatePending bool `json:"upd_pending"`
RevalPending bool `json:"reval_pending"`
UseRevalPending bool `json:"use_reval_pending"`
HostId int `json:"host_id"`
Status string `json:"status"`
ParentPending bool `json:"parent_pending"`
ParentRevalPending bool `json:"parent_reval_pending"`
}
// Upgrade converts the deprecated ServerUpdateStatus to a
// ServerUpdateStatusV4 struct.
func (sus ServerUpdateStatus) Upgrade() ServerUpdateStatusV4 {
return ServerUpdateStatusV4{
HostName: sus.HostName,
UpdatePending: sus.UpdatePending,
RevalPending: sus.RevalPending,
UseRevalPending: sus.UseRevalPending,
HostId: sus.HostId,
Status: sus.Status,
ParentPending: sus.ParentPending,
ParentRevalPending: sus.ParentRevalPending,
}
}
// ServerUpdateStatusResponseV40 is the type of a response from the Traffic
// Ops API to a request to its /servers/{{host name}}/update_status endpoint
// in API version 4.0.
type ServerUpdateStatusResponseV40 struct {
Response []ServerUpdateStatusV40 `json:"response"`
Alerts
}
// ServerUpdateStatusResponseV4 is the type of a response from the Traffic
// Ops API to a request to its /servers/{{host name}}/update_status endpoint
// in the latest minor version of API version 4.
type ServerUpdateStatusResponseV4 = ServerUpdateStatusResponseV40
// ServerPutStatus is a request to change the Status of a server, optionally
// with an explanation.
type ServerPutStatus struct {
Status util.JSONNameOrIDStr `json:"status"`
OfflineReason *string `json:"offlineReason"`
}
// ServerInfo is a stripped-down type containing a subset of information for a
// server.
//
// This is primarily only useful internally in Traffic Ops for
// constructing/examining the relationships between servers and other ATC
// objects. That is to say, for most other purposes a ServerV4 would be better
// suited.
type ServerInfo struct {
Cachegroup string
CachegroupID int
CDNID int
DomainName string
HostName string
ID int
Status string
Type string
}
// ServerDetail is a type that contains a superset of the information available
// in a ServerNullable.
//
// This should NOT be used in general, it's almost always better to use a
// proper server representation. However, this structure is not deprecated
// because it is embedded in structures still in use, and its future is unclear
// and undecided.
//
// Deprecated: The API versions that use this representation have been
// deprecated, newer structures like ServerV4 should be used instead.
type ServerDetail struct {
CacheGroup *string `json:"cachegroup" db:"cachegroup"`
CDNName *string `json:"cdnName" db:"cdn_name"`
DeliveryServiceIDs []int64 `json:"deliveryservices,omitempty"`
DomainName *string `json:"domainName" db:"domain_name"`
GUID *string `json:"guid" db:"guid"`
HardwareInfo map[string]string `json:"hardwareInfo"`
HostName *string `json:"hostName" db:"host_name"`
HTTPSPort *int `json:"httpsPort" db:"https_port"`
ID *int `json:"id" db:"id"`
ILOIPAddress *string `json:"iloIpAddress" db:"ilo_ip_address"`
ILOIPGateway *string `json:"iloIpGateway" db:"ilo_ip_gateway"`
ILOIPNetmask *string `json:"iloIpNetmask" db:"ilo_ip_netmask"`
ILOPassword *string `json:"iloPassword" db:"ilo_password"`
ILOUsername *string `json:"iloUsername" db:"ilo_username"`
MgmtIPAddress *string `json:"mgmtIpAddress" db:"mgmt_ip_address"`
MgmtIPGateway *string `json:"mgmtIpGateway" db:"mgmt_ip_gateway"`
MgmtIPNetmask *string `json:"mgmtIpNetmask" db:"mgmt_ip_netmask"`
OfflineReason *string `json:"offlineReason" db:"offline_reason"`
PhysLocation *string `json:"physLocation" db:"phys_location"`
Profile *string `json:"profile" db:"profile"`
ProfileDesc *string `json:"profileDesc" db:"profile_desc"`
Rack *string `json:"rack" db:"rack"`
Status *string `json:"status" db:"status"`
TCPPort *int `json:"tcpPort" db:"tcp_port"`
Type string `json:"type" db:"server_type"`
XMPPID *string `json:"xmppId" db:"xmpp_id"`
XMPPPasswd *string `json:"xmppPasswd" db:"xmpp_passwd"`
}
// ServerQueueUpdateRequest encodes the request data for the POST
// servers/{{ID}}/queue_update endpoint.
type ServerQueueUpdateRequest struct {
Action string `json:"action"`
}
// ServerQueueUpdateResponse decodes the full response with alerts from the POST
// servers/{{ID}}/queue_update endpoint.
type ServerQueueUpdateResponse struct {
Response ServerQueueUpdate `json:"response"`
Alerts
}
// ServerQueueUpdate decodes the update data from the POST
// servers/{{ID}}/queue_update endpoint.
type ServerQueueUpdate struct {
ServerID util.JSONIntStr `json:"serverId"`
Action string `json:"action"`
}