Skip to content
This repository was archived by the owner on Nov 24, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*

Licensed 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.

*/

-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied

-- alter server
ALTER TABLE server
DROP COLUMN IF EXISTS interface_name,
DROP COLUMN IF EXISTS interface_mtu,
DROP COLUMN IF EXISTS ip_address,
DROP COLUMN IF EXISTS ip_netmask,
DROP COLUMN IF EXISTS ip_gateway,
DROP COLUMN IF EXISTS ip6_address,
DROP COLUMN IF EXISTS ip6_gateway,
DROP COLUMN IF EXISTS mgmt_ip_address,
DROP COLUMN IF EXISTS mgmt_ip_netmask,
DROP COLUMN IF EXISTS mgmt_ip_gateway,
DROP COLUMN IF EXISTS ilo_ip_address,
DROP COLUMN IF EXISTS ilo_ip_netmask,
DROP COLUMN IF EXISTS ilo_ip_gateway;

-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back

ALTER TABLE server
ADD COLUMN interface_name text NOT NULL,
ADD COLUMN interface_mtu bigint DEFAULT '9000'::bigint NOT NULL,
ADD COLUMN ip_address text NOT NULL,
ADD COLUMN ip_netmask text NOT NULL,
ADD COLUMN ip_gateway text NOT NULL,
ADD COLUMN ip6_address text,
ADD COLUMN ip6_gateway text,
ADD COLUMN mgmt_ip_address text,
ADD COLUMN mgmt_ip_netmask text,
ADD COLUMN mgmt_ip_gateway text,
ADD COLUMN ilo_ip_address text,
ADD COLUMN ilo_ip_netmask text,
ADD COLUMN ilo_ip_gateway text;
250 changes: 197 additions & 53 deletions traffic_ops/traffic_ops_golang/server/servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (
"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/api"
"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/interface"
"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/ip"
"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/tovalidate"

validation "github.com/go-ozzo/ozzo-validation"
Expand Down Expand Up @@ -264,22 +266,22 @@ s.guid,
s.host_name,
s.https_port,
s.id,
s.ilo_ip_address,
s.ilo_ip_gateway,
s.ilo_ip_netmask,
host(ipi.ipv4) as ilo_ip_address,
ipi.ipv4_gateway as ilo_ip_gateway,
netmask(ipi.ipv4) as ilo_ip_netmask,
s.ilo_password,
s.ilo_username,
COALESCE(s.interface_mtu, ` + strconv.Itoa(JumboFrameBPS) + `) as interface_mtu,
s.interface_name,
s.ip6_address,
s.ip6_gateway,
s.ip_address,
s.ip_gateway,
s.ip_netmask,
COALESCE(if.interface_mtu, ` + strconv.Itoa(JumboFrameBPS) + `) as interface_mtu,
if.interface_name as interface_name,
ipp.ipv6 as ip6_address,
ipp.ipv6_gateway as ip6_gateway,
host(ipp.ipv4) as ip_address,
ipp.ipv4_gateway as ip_gateway,
netmask(ipp.ipv4) as ip_netmask,
s.last_updated,
s.mgmt_ip_address,
s.mgmt_ip_gateway,
s.mgmt_ip_netmask,
host(ipm.ipv4) as mgmt_ip_address,
ipm.ipv4_gateway as mgmt_ip_gateway,
netmask(ipm.ipv4) as mgmt_ip_netmask,
s.offline_reason,
pl.name as phys_location,
s.phys_location as phys_location_id,
Expand All @@ -306,7 +308,11 @@ JOIN cdn cdn ON s.cdn_id = cdn.id
JOIN phys_location pl ON s.phys_location = pl.id
JOIN profile p ON s.profile = p.id
JOIN status st ON s.status = st.id
JOIN type t ON s.type = t.id`
JOIN type t ON s.type = t.id
JOIN ip ipp ON s.id = ipp.server and ipp.type = (SELECT id FROM type WHERE name='IP_PRIMARY')
JOIN ip ipm ON s.id = ipm.server and ipm.type = (SELECT id FROM type WHERE name='IP_MANAGEMENT')
JOIN ip ipi ON s.id = ipi.server and ipi.type = (SELECT id FROM type WHERE name='IP_ILO')
JOIN interface if ON s.id = if.server and if.id = ipp.interface`

return selectStmt
}
Expand Down Expand Up @@ -334,6 +340,7 @@ func (server *TOServer) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
return tc.DBError, tc.SystemError
}

// update record in table server
log.Debugf("about to run exec query: %s with server: %++v", updateQuery(), server)
resultRows, err := tx.NamedQuery(updateQuery(), server)
if err != nil {
Expand Down Expand Up @@ -370,6 +377,69 @@ func (server *TOServer) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
log.Errorln(err)
return tc.DBError, tc.SystemError
}

// update record in table interface
primaryIP, err, errType := getIpByServerAndType(db, *server.ID, "IP_PRIMARY")
if err != nil {
log.Errorf("can not get primary ip for server %d: %+v", *server.ID, err)
return err, errType
}

intfUpdate := intf.TOInterface{
ID: primaryIP.InterfaceID,
ServerID: server.ID,
InterfaceName: server.InterfaceName,
InterfaceMtu: server.InterfaceMtu,
}

err, errType = intfUpdate.UpdateExecAndCheck(tx)
if err != nil {
log.Errorf("update interface error during server updating: %+v", err)
return err, errType
}

// handle primary ip
primaryIP.IPAddress = server.IPAddress
primaryIP.IPGateway = server.IPGateway
primaryIP.IPNetmask = server.IPNetmask
primaryIP.IP6Address = server.IP6Address
primaryIP.IP6Gateway = server.IP6Gateway
err, errType = primaryIP.UpdateExecAndCheck(tx)
if err != nil {
log.Errorf("update primary ip error during server updating: %+v", err)
return err, errType
}

// handle management ip
managementIP, err, errType := getIpByServerAndType(db, *server.ID, "IP_MANAGEMENT")
if err != nil {
log.Errorf("can not get management ip for server %d: %+v", *server.ID, err)
return err, errType
}
managementIP.IPAddress = server.MgmtIPAddress
managementIP.IPGateway = server.MgmtIPGateway
managementIP.IPNetmask = server.MgmtIPNetmask
err, errType = managementIP.UpdateExecAndCheck(tx)
if err != nil {
log.Errorf("update management ip error during server updating: %+v", err)
return err, errType
}

// handle ilo ip
iloIP, err, errType := getIpByServerAndType(db, *server.ID, "IP_ILO")
if err != nil {
log.Errorf("can not get ilo ip for server %d: %+v", *server.ID, err)
return err, errType
}
iloIP.IPAddress = server.MgmtIPAddress
iloIP.IPGateway = server.MgmtIPGateway
iloIP.IPNetmask = server.MgmtIPNetmask
err, errType = iloIP.UpdateExecAndCheck(tx)
if err != nil {
log.Errorf("update ilo ip error during server updating: %+v", err)
return err, errType
}

server.SetID(id)
server.LastUpdated = &lastUpdated
err = tx.Commit()
Expand All @@ -381,6 +451,44 @@ func (server *TOServer) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
return nil, tc.NoError
}

//get the unique IP record by server and ip type
//ip type includes IP_PRIMARY, IP_MANAGEMENT and IP_ILO
func getIpByServerAndType(db *sqlx.DB, serverID int, ipType string) (*ip.TOIP, error, tc.ApiErrorType) {
var ipTypeID int
queryTypeStr := fmt.Sprintf("SELECT id FROM type WHERE name='%s'", ipType)
err := db.Get(&ipTypeID, queryTypeStr)
if err != nil {
log.Errorf("received error: %+v from get ID for type %s", err, ipType)
return nil, fmt.Errorf("can not get type id for type %s", ipType), tc.SystemError
}

queryIpStr := ip.SelectQuery() + " where ip.server=$1 and ip.type=$2"
log.Debugln("Query is ", queryIpStr)
rows, err := db.Queryx(queryIpStr, serverID, ipTypeID)
if err != nil {
log.Errorf("received error: %+v from get IP for server %d and type %d", err, serverID, ipTypeID)
return nil, tc.DBError, tc.SystemError
}
defer rows.Close()

var ipFound ip.TOIP
if rows.Next() {
if err = rows.StructScan(&ipFound); err != nil {
log.Errorf("received error: %+v from scan IP", err)
return nil, tc.DBError, tc.SystemError
}
if rows.Next() {
log.Errorf("too many ips found for server %d and type %s", serverID, ipType)
return nil, fmt.Errorf("too many ips found for server %d and type %s", serverID, ipType), tc.SystemError
}
} else {
log.Errorf("no ip found for server %d and type %s", serverID, ipType)
return nil, fmt.Errorf("no ip found for server %d and type %s", serverID, ipType), tc.SystemError
}

return &ipFound, nil, tc.NoError
}

func updateQuery() string {
query := `UPDATE
server SET
Expand All @@ -389,21 +497,8 @@ cdn_id=:cdn_id,
domain_name=:domain_name,
host_name=:host_name,
https_port=:https_port,
ilo_ip_address=:ilo_ip_address,
ilo_ip_netmask=:ilo_ip_netmask,
ilo_ip_gateway=:ilo_ip_gateway,
ilo_username=:ilo_username,
ilo_password=:ilo_password,
interface_mtu=:interface_mtu,
interface_name=:interface_name,
ip6_address=:ip6_address,
ip6_gateway=:ip6_gateway,
ip_address=:ip_address,
ip_netmask=:ip_netmask,
ip_gateway=:ip_gateway,
mgmt_ip_address=:mgmt_ip_address,
mgmt_ip_netmask=:mgmt_ip_netmask,
mgmt_ip_gateway=:mgmt_ip_gateway,
offline_reason=:offline_reason,
phys_location=:phys_location_id,
profile=:profile_id,
Expand Down Expand Up @@ -446,6 +541,7 @@ func (server *TOServer) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
server.XMPPID = server.HostName
}

// create record in table server
resultRows, err := tx.NamedQuery(insertQuery(), server)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
Expand Down Expand Up @@ -480,6 +576,80 @@ func (server *TOServer) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
log.Errorln(err)
return tc.DBError, tc.SystemError
}

// create record in table interface
intfCreate := intf.TOInterface{
ServerID: &id,
InterfaceName: server.InterfaceName,
InterfaceMtu: server.InterfaceMtu,
}

err, errType := intfCreate.InsertExecAndCheck(tx)
if err != nil {
return err, errType
}

// create record for primary ip in table ip
var ipType int
queryStr := "SELECT id FROM type WHERE name='IP_PRIMARY'"
err = db.Get(&ipType, queryStr)
if err != nil {
log.Errorf("received error: %+v from SELECT id FROM type", err)
return tc.DBError, tc.SystemError
}
ipCreate := ip.TOIP{
ServerID: &id,
TypeID: &ipType,
InterfaceID: intfCreate.ID,
IPAddress: server.IPAddress,
IPGateway: server.IPGateway,
IPNetmask: server.IPNetmask,
IP6Address: server.IP6Address,
IP6Gateway: server.IP6Gateway,
}
err, errType = ipCreate.InsertExecAndCheck(tx)
if err != nil {
return err, errType
}

// create record for management ip in table ip
queryStr = "SELECT id FROM type WHERE name='IP_MANAGEMENT'"
err = db.Get(&ipType, queryStr)
if err != nil {
log.Errorf("received error: %+v from SELECT id FROM type", err)
return tc.DBError, tc.SystemError
}
ipCreate = ip.TOIP{
ServerID: &id,
TypeID: &ipType,
IPAddress: server.MgmtIPAddress,
IPGateway: server.MgmtIPGateway,
IPNetmask: server.MgmtIPNetmask,
}
err, errType = ipCreate.InsertExecAndCheck(tx)
if err != nil {
return err, errType
}

// create record for ilo ip in table ip
queryStr = "SELECT id FROM type WHERE name='IP_ILO'"
err = db.Get(&ipType, queryStr)
if err != nil {
log.Errorf("received error: %+v from SELECT id FROM type", err)
return tc.DBError, tc.SystemError
}
ipCreate = ip.TOIP{
ServerID: &id,
TypeID: &ipType,
IPAddress: server.ILOIPAddress,
IPGateway: server.ILOIPGateway,
IPNetmask: server.ILOIPNetmask,
}
err, errType = ipCreate.InsertExecAndCheck(tx)
if err != nil {
return err, errType
}

server.SetKeys(map[string]interface{}{"id": id})
server.LastUpdated = &lastUpdated
err = tx.Commit()
Expand All @@ -498,21 +668,8 @@ cdn_id,
domain_name,
host_name,
https_port,
ilo_ip_address,
ilo_ip_netmask,
ilo_ip_gateway,
ilo_username,
ilo_password,
interface_mtu,
interface_name,
ip6_address,
ip6_gateway,
ip_address,
ip_netmask,
ip_gateway,
mgmt_ip_address,
mgmt_ip_netmask,
mgmt_ip_gateway,
offline_reason,
phys_location,
profile,
Expand All @@ -528,21 +685,8 @@ upd_pending) VALUES (
:domain_name,
:host_name,
:https_port,
:ilo_ip_address,
:ilo_ip_netmask,
:ilo_ip_gateway,
:ilo_username,
:ilo_password,
:interface_mtu,
:interface_name,
:ip6_address,
:ip6_gateway,
:ip_address,
:ip_netmask,
:ip_gateway,
:mgmt_ip_address,
:mgmt_ip_netmask,
:mgmt_ip_gateway,
:offline_reason,
:phys_location_id,
:profile_id,
Expand Down