You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by sh...@apache.org on 2022/05/17 21:25:22 UTC
[trafficcontrol] branch master updated: Remove `/servers/details` from APIv4 (#6819)
This is an automated email from the ASF dual-hosted git repository.
shamrick pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/master by this push:
new b9cdfd5b9d Remove `/servers/details` from APIv4 (#6819)
b9cdfd5b9d is described below
commit b9cdfd5b9d150a17437c4c22d6cbdcd0a26066cb
Author: ocket8888 <oc...@apache.org>
AuthorDate: Tue May 17 15:25:17 2022 -0600
Remove `/servers/details` from APIv4 (#6819)
* Add deprecation notices, remove v4 handling, fix #6800
* Update documentation - add deprecation notices to v3, remove from v4
* Update clients - remove from v4, add deprecation notices to v3
* Update CHANGELOG
* fix unable to get server details by hostname if physloc not also provided
* Fix embedded 'response' object
---
CHANGELOG.md | 4 +-
docs/source/api/v3/servers_details.rst | 3 +
docs/source/api/v4/servers_details.rst | 192 ---------------------
.../clients/python/trafficops/tosession.py | 7 +-
traffic_ops/testing/api/v4/servers_test.go | 33 ----
traffic_ops/traffic_ops_golang/routing/routes.go | 3 -
traffic_ops/traffic_ops_golang/server/detail.go | 175 +++++++++++--------
traffic_ops/v3-client/server.go | 4 +
traffic_ops/v4-client/server.go | 11 --
9 files changed, 114 insertions(+), 318 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 768c04969c..e8e85c9a58 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,11 +17,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Traffic Monitor: Add support for `access.log` to TM.
- Added functionality for login to provide a Bearer token and for that token to be later used for authorization.
- [Traffic Ops] Added support for backend configurations so that Traffic Ops can act as a reverse proxy for these services [#6754](https://github.com/apache/trafficcontrol/pull/6754).
-- Added functionality for CDN locks, so that they can be shared amongst a list of specified usernames.
+- Added functionality for CDN locks, so that they can be shared amongst a list of specified usernames.
- [Traffic Ops | Traffic Go Clients | T3C] Add additional timestamp fields to server for queuing and dequeueing config and revalidate updates.
- Added layered profile feature to 4.0 for `GET` /servers/, `POST` /servers/, `PUT` /servers/{id} and `DELETE` /servers/{id}.
- Added a Traffic Ops endpoint and Traffic Portal page to view all CDNi configuration update requests and approve or deny.
-- Added layered profile feature to 4.0 for `GET` /servers/details.
- Added layered profile feature to 4.0 for `GET` /deliveryservices/{id}/servers/ and /deliveryservices/{id}/servers/eligible.
### Fixed
@@ -57,6 +56,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Replace `forever` with `pm2` for process management of the traffic portal node server to remediate security issues.
- Removed the Traffic Monitor `peer_polling_protocol` option. Traffic Monitor now just uses hostnames to request peer states, which can be handled via IPv4 or IPv6 depending on the underlying IP version in use.
- Dropped CentOS 8 support
+- The `/servers/details` endpoint of the Traffic Ops API has been dropped in version 4.0, and marked deprecated in earlier versions.
### Changed
- [#6654](https://github.com/apache/trafficcontrol/issues/6654) Traffic Monitor now uses the TO API 4.0 by default and falls back to 3.1
diff --git a/docs/source/api/v3/servers_details.rst b/docs/source/api/v3/servers_details.rst
index 4dfe2e96ec..f1e746aa45 100644
--- a/docs/source/api/v3/servers_details.rst
+++ b/docs/source/api/v3/servers_details.rst
@@ -20,6 +20,9 @@
*******************
Retrieves details of :ref:`tp-configure-servers`.
+.. deprecated:: 3.1
+ This endpoint has been removed from the latest version of the API, and clients are advised to use :ref:`to-api-v3-servers` instead.
+
``GET``
=======
diff --git a/docs/source/api/v4/servers_details.rst b/docs/source/api/v4/servers_details.rst
deleted file mode 100644
index dc0a917b50..0000000000
--- a/docs/source/api/v4/servers_details.rst
+++ /dev/null
@@ -1,192 +0,0 @@
-..
-..
-.. 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.
-..
-
-.. _to-api-servers-details:
-
-*******************
-``servers/details``
-*******************
-Retrieves details of :ref:`tp-configure-servers`.
-
-
-``GET``
-=======
-:Auth. Required: Yes
-:Roles Required: None
-:Permissions Required: SERVER:READ, DELIVERY-SERVICE:READ, CDN:READ, PHYSICAL-LOCATION:READ, CACHE-GROUP:READ, TYPE:READ, PROFILE:READ
-:Response Type: Array
-
-.. note:: On top of the response including the response key that is of type array it will also include the keys ``limit``, ``orderby``, and ``size``.
-
-Request Structure
------------------
-.. table:: Request Query Parameters
-
- +----------------+----------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+
- | Name | Required | Description |
- +================+========================================+================================================================================================================================================================+
- | hostName | Required if no physLocationID provided | Return only the servers with this (short) hostname. Capitalization of "hostName" is important. |
- +----------------+----------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+
- | physLocationID | Required if no hostName provided | Return only servers with this integral, unique identifier for the physical location where the server resides. Capitalization of "physLocationID" is important. |
- +----------------+----------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+
-
-.. code-block:: http
- :caption: Request Example
-
- GET /api/4.0/servers/details?hostName=edge HTTP/1.1
- User-Agent: python-requests/2.22.0
- Accept-Encoding: gzip, deflate
- Accept: */*
- Connection: keep-alive
- Cookie: mojolicious=...
-
-Response Structure
-------------------
-:limit: The maximum size of the ``response`` array, also indicative of the number of results per page using the pagination requested by the query parameters (if any) - this should be the same as the ``limit`` query parameter (if given)
-:orderby: A string that names the field by which the elements of the ``response`` array are ordered - should be the same as the ``orderby`` request query parameter (if given)
-:response: An array of objects, each of which represents the details of a given :ref:`Server <tp-configure-servers>`.
-
- :cachegroup: A string that is the :ref:`name of the Cache Group <cache-group-name>` to which the server belongs
- :cdnName: Name of the CDN to which the server belongs
- :deliveryservices: An array of integral, unique identifiers for :term:`Delivery Services` to which this server belongs
- :domainName: The domain part of the server's :abbr:`FQDN (Fully Qualified Domain Name)`
- :guid: An identifier used to uniquely identify the server
-
- .. note:: This is a legacy key which only still exists for compatibility reasons - it should always be ``null``
-
- :hostName: The (short) hostname of the server
- :httpsPort: The port on which the server listens for incoming HTTPS connections/requests
- :id: An integral, unique identifier for this server
- :iloIpAddress: The IPv4 address of the server's :abbr:`ILO (Integrated Lights-Out)` service\ [1]_
- :iloIpGateway: The IPv4 gateway address of the server's :abbr:`ILO (Integrated Lights-Out)` service\ [1]_
- :iloIpNetmask: The IPv4 subnet mask of the server's :abbr:`ILO (Integrated Lights-Out)` service\ [1]_
- :iloPassword: The password of the of the server's :abbr:`ILO (Integrated Lights-Out)` service user\ [1]_ - displays as simply ``******`` if the currently logged-in user does not have the 'admin' or 'operations' :term:`Role(s) <Role>`
- :iloUsername: The user name for the server's :abbr:`ILO (Integrated Lights-Out)` service\ [1]_
- :interfaces: An array of interface and IP address information
-
- :max_bandwidth: The maximum allowed bandwidth for this interface to be considered "healthy" by Traffic Monitor. This has no effect if `monitor` is not true. Values are in kb/s. The value `0` means "no limit".
- :monitor: A boolean indicating if Traffic Monitor should monitor this interface
- :mtu: The :abbr:`MTU (Maximum Transmission Unit)` to configure for ``interfaceName``
-
- .. seealso:: `The Wikipedia article on Maximum Transmission Unit <https://en.wikipedia.org/wiki/Maximum_transmission_unit>`_
-
- :name: The network interface name used by the server.
-
- :ipAddresses: An array of the IP address information for the interface
-
- :address: The IPv4 or IPv6 address and subnet mask of the server - applicable for the interface ``name``
- :gateway: The IPv4 or IPv6 gateway address of the server - applicable for the interface ``name``
- :service_address: A boolean determining if content will be routed to the IP address
-
- :routerHostName: The human-readable name of the router responsible for reaching this server's interface.
- :routerPortName: The human-readable name of the port used by the router responsible for reaching this server's interface.
-
- :mgmtIpAddress: The IPv4 address of the server's management port
- :mgmtIpGateway: The IPv4 gateway of the server's management port
- :mgmtIpNetmask: The IPv4 subnet mask of the server's management port
- :offlineReason: A user-entered reason why the server is in ADMIN_DOWN or OFFLINE status
- :physLocation: The name of the physical location where the server resides
- :profileNames: List of :ref:`profile-name` of the :term:`Profiles` used by this server
- :rack: A string indicating "server rack" location
- :status: The status of the server
-
- .. seealso:: :ref:`health-proto`
-
- :tcpPort: The port on which this server listens for incoming TCP connections
-
- .. note:: This is typically thought of as synonymous with "HTTP port", as the port specified by ``httpsPort`` may also be used for incoming TCP connections.
-
- :type: The name of the 'type' of this server
- :xmppId: A system-generated UUID used to generate a server hashId for use in Traffic Router's consistent hashing algorithm. This value is set when a server is created and cannot be changed afterwards.
- :xmppPasswd: The password used in XMPP communications with the server
-
-:size: The page number - if pagination was requested in the query parameters, else ``0`` to indicate no pagination - of the results represented by the ``response`` array. This is named "size" for legacy reasons
-
-.. code-block:: http
- :caption: Response Example
-
- HTTP/1.1 200 OK
- Access-Control-Allow-Credentials: true
- Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Set-Cookie, Cookie
- Access-Control-Allow-Methods: POST,GET,OPTIONS,PUT,DELETE
- Access-Control-Allow-Origin: *
- Content-Encoding: gzip
- Content-Type: application/json
- Set-Cookie: mojolicious=...; Path=/; Expires=Mon, 24 Feb 2020 01:27:36 GMT; Max-Age=3600; HttpOnly
- Whole-Content-Sha512: HW2F3CEpohNAvNlEDhUfXmtwpEka4dwUWFVUSSjW98aXiv10vI6ysRIcC2P9huabCz5fdHqY3tp0LR4ekwEHqw==
- X-Server-Name: traffic_ops_golang/
- Date: Mon, 24 Feb 2020 00:27:36 GMT
- Content-Length: 493
-
- {
- "limit": 1000,
- "orderby": "hostName",
- "response": [
- {
- "cachegroup": "CDN_in_a_Box_Edge",
- "cdnName": "CDN-in-a-Box",
- "deliveryservices": [
- 1
- ],
- "domainName": "infra.ciab.test",
- "guid": null,
- "hardwareInfo": null,
- "hostName": "edge",
- "httpsPort": 443,
- "id": 5,
- "iloIpAddress": "",
- "iloIpGateway": "",
- "iloIpNetmask": "",
- "iloPassword": "",
- "iloUsername": "",
- "mgmtIpAddress": "",
- "mgmtIpGateway": "",
- "mgmtIpNetmask": "",
- "offlineReason": "",
- "physLocation": "Apachecon North America 2018",
- "profileNames": ["ATS_EDGE_TIER_CACHE"],
- "rack": "",
- "status": "REPORTED",
- "tcpPort": 80,
- "type": "EDGE",
- "xmppId": "edge",
- "xmppPasswd": "",
- "interfaces": [
- { "ipAddresses": [
- {
- "address": "172.16.239.100",
- "gateway": "172.16.239.1",
- "service_address": true
- },
- {
- "address": "fc01:9400:1000:8::100",
- "gateway": "fc01:9400:1000:8::1",
- "service_address": true
- }
- ],
- "max_bandwidth": 0,
- "monitor": true,
- "mtu": 1500,
- "name": "eth0",
- "routerHostName": "",
- "routerPortName": ""
- }
- ]
- }
- ],
- "size": 1
- }
-
-.. [1] For more information see the `Wikipedia page on Lights-Out management <https://en.wikipedia.org/wiki/Out-of-band_management>`_\ .
diff --git a/traffic_control/clients/python/trafficops/tosession.py b/traffic_control/clients/python/trafficops/tosession.py
index f907911f04..150b51311d 100644
--- a/traffic_control/clients/python/trafficops/tosession.py
+++ b/traffic_control/clients/python/trafficops/tosession.py
@@ -1648,13 +1648,16 @@ class TOSession(RestApiSession):
:raises: Union[LoginError, OperationError]
"""
- @api_request('get', 'servers/details?hostName={name}', ('3.0','4.0',))
+ @api_request('get', 'servers/details?hostName={name}', ('3.0',))
def get_server_details(self, name=None):
"""
Get servers/details
- :ref:`to-api-servers-details`
+ :ref:`to-api-v3-servers-details`
:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
:raises: Union[LoginError, OperationError]
+
+ .. deprecated:: 3.0
+ The endpoint this represents has been removed from APIv4 and clients should use get_servers instead.
"""
@api_request('post', 'servercheck', ('3.0',))
diff --git a/traffic_ops/testing/api/v4/servers_test.go b/traffic_ops/testing/api/v4/servers_test.go
index 4adf0d8345..a6f1680a4d 100644
--- a/traffic_ops/testing/api/v4/servers_test.go
+++ b/traffic_ops/testing/api/v4/servers_test.go
@@ -42,7 +42,6 @@ func TestServers(t *testing.T) {
header.Set(rfc.IfUnmodifiedSince, time)
UpdateTestServers(t)
UpdateTestServersWithHeaders(t, header)
- GetTestServersDetails(t)
GetTestServers(t)
GetTestServersIMSAfterChange(t, header)
GetTestServersQueryParameters(t)
@@ -657,38 +656,6 @@ func GetTestServers(t *testing.T) {
}
}
-func GetTestServersDetails(t *testing.T) {
- opts := client.NewRequestOptions()
- for _, server := range testData.Servers {
- if server.HostName == nil {
- t.Errorf("found server with nil hostname: %+v", server)
- continue
- }
- opts.QueryParameters.Set("hostName", *server.HostName)
- resp, _, err := TOSession.GetServersDetails(opts)
- if err != nil {
- t.Errorf("cannot get Server Details: %v - alerts: %+v", err, resp.Alerts)
- }
- if len(resp.Response) == 0 {
- t.Fatal("no servers in response, quitting")
- }
- if len(resp.Response[0].ServerInterfaces) == 0 {
- t.Fatalf("no interfaces to check, quitting")
- }
- if len(server.Interfaces) == 0 {
- t.Fatalf("no interfaces to check, quitting")
- }
-
- // just check the first interface for noe
- if resp.Response[0].ServerInterfaces[0].RouterHostName != server.Interfaces[0].RouterHostName {
- t.Errorf("expected router host name to be %s, but got %s", server.Interfaces[0].RouterHostName, resp.Response[0].ServerInterfaces[0].RouterHostName)
- }
- if resp.Response[0].ServerInterfaces[0].RouterPortName != server.Interfaces[0].RouterPortName {
- t.Errorf("expected router port to be %s, but got %s", server.Interfaces[0].RouterPortName, resp.Response[0].ServerInterfaces[0].RouterPortName)
- }
- }
-}
-
func GetTestServersQueryParameters(t *testing.T) {
dses, _, err := TOSession.GetDeliveryServices(client.RequestOptions{QueryParameters: url.Values{"xmlId": []string{"ds1"}}})
if err != nil {
diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go b/traffic_ops/traffic_ops_golang/routing/routes.go
index cbfa250307..452ab76157 100644
--- a/traffic_ops/traffic_ops_golang/routing/routes.go
+++ b/traffic_ops/traffic_ops_golang/routing/routes.go
@@ -311,9 +311,6 @@ func Routes(d ServerData) ([]Route, http.Handler, error) {
{Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodGet, Path: `servercheck/extensions$`, Handler: extensions.Get, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"SERVER-CHECK:READ", "SERVER:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 4834985993},
{Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodDelete, Path: `servercheck/extensions/{id}$`, Handler: extensions.Delete, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"SERVER-CHECK:DELETE", "SERVER-CHECK:READ", "SERVER:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 4804982993},
- //Server Details
- {Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodGet, Path: `servers/details/?$`, Handler: server.GetDetailParamHandler, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"SERVER:READ", "DELIVERY-SERVICE:READ", "CDN:READ", "PHYSICAL-LOCATION:READ", "CACHE-GROUP:READ", "TYPE:READ", "PROFILE:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 42612647143},
-
//Server status
{Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodPut, Path: `servers/{id}/status$`, Handler: server.UpdateStatusHandler, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:READ", "STATUS:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 4766638513},
{Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodPost, Path: `servers/{id}/queue_update$`, Handler: server.QueueUpdateHandler, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:QUEUE", "SERVER:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 41894713},
diff --git a/traffic_ops/traffic_ops_golang/server/detail.go b/traffic_ops/traffic_ops_golang/server/detail.go
index 287e0e4011..a327a40595 100644
--- a/traffic_ops/traffic_ops_golang/server/detail.go
+++ b/traffic_ops/traffic_ops_golang/server/detail.go
@@ -28,6 +28,7 @@ import (
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
+ "github.com/apache/trafficcontrol/lib/go-log"
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/lib/go-util"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
@@ -36,27 +37,32 @@ import (
"github.com/lib/pq"
)
+// GetDetailParamHandler handles GET requests to /servers/details (the name
+// includes "Param" for legacy reasons).
+//
+// Deprecated: This endpoint has been removed from APIv4.
func GetDetailParamHandler(w http.ResponseWriter, r *http.Request) {
+ alt := "/servers"
inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil)
if userErr != nil || sysErr != nil {
- api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
+ api.HandleDeprecatedErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr, &alt)
return
}
defer inf.Close()
hostName := inf.Params["hostName"]
physLocationIDStr := inf.Params["physLocationID"]
- physLocationID := -1
+ var physLocationID int
if physLocationIDStr != "" {
- err := error(nil)
+ var err error
physLocationID, err = strconv.Atoi(physLocationIDStr)
if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, errors.New("physLocationID parameter is not an integer"), nil)
+ api.HandleDeprecatedErr(w, r, inf.Tx.Tx, http.StatusBadRequest, errors.New("physLocationID parameter is not an integer"), err, &alt)
return
}
}
if hostName == "" && physLocationIDStr == "" {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, errors.New("missing required fields: 'hostName' or 'physLocationID'"), nil)
+ api.HandleDeprecatedErr(w, r, inf.Tx.Tx, http.StatusBadRequest, errors.New("missing required fields: 'hostName' or 'physLocationID'"), nil, &alt)
return
}
orderBy := "hostName"
@@ -65,22 +71,22 @@ func GetDetailParamHandler(w http.ResponseWriter, r *http.Request) {
}
limit := 1000
if limitStr, ok := inf.Params["limit"]; ok {
- err := error(nil)
+ var err error
limit, err = strconv.Atoi(limitStr)
if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, errors.New("limit parameter is not an integer"), nil)
+ api.HandleDeprecatedErr(w, r, inf.Tx.Tx, http.StatusBadRequest, errors.New("limit parameter is not an integer"), err, &alt)
return
}
}
servers, err := getDetailServers(inf.Tx.Tx, inf.User, hostName, physLocationID, util.CamelToSnakeCase(orderBy), limit, *inf.Version)
- respVals := map[string]interface{}{
- "orderby": orderBy,
- "limit": limit,
- "size": len(servers),
+ if err != nil {
+ api.HandleDeprecatedErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, err, &alt)
}
+ var resp interface{}
+ size := len(servers)
if inf.Version.Major <= 2 {
- v11ServerList := []tc.ServerDetailV11{}
+ v11ServerList := make([]tc.ServerDetailV11, 0, size)
for _, server := range servers {
interfaces := server.ServerInterfaces
routerHostName := ""
@@ -93,24 +99,23 @@ func GetDetailParamHandler(w http.ResponseWriter, r *http.Request) {
v11server := tc.ServerDetailV11{}
v11server.ServerDetail, err = dbhelpers.GetServerDetailFromV4(server, inf.Tx.Tx)
if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("failed to GetServerDetailFromV4: %w", err))
+ api.HandleDeprecatedErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("failed to GetServerDetailFromV4: %w", err), &alt)
return
}
v11server.RouterHostName = &routerHostName
v11server.RouterPortName = &routerPortName
legacyInterface, err := tc.V4InterfaceInfoToLegacyInterfaces(interfaces)
if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("converting to server detail v11: "+err.Error()))
+ api.HandleDeprecatedErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("converting to server detail v11: %w", err), &alt)
return
}
v11server.LegacyInterfaceDetails = legacyInterface
v11ServerList = append(v11ServerList, v11server)
}
- api.RespWriterVals(w, r, inf.Tx.Tx, respVals)(v11ServerList, err)
- return
+ resp = v11ServerList
} else if inf.Version.Major <= 3 {
- v3ServerList := []tc.ServerDetailV30{}
+ v3ServerList := make([]tc.ServerDetailV30, 0, size)
for _, server := range servers {
v3Server := tc.ServerDetailV30{}
interfaces := server.ServerInterfaces
@@ -123,33 +128,49 @@ func GetDetailParamHandler(w http.ResponseWriter, r *http.Request) {
}
v3Server.ServerDetail, err = dbhelpers.GetServerDetailFromV4(server, inf.Tx.Tx)
if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("failed to GetServerDetailFromV4: %w", err))
+ api.HandleDeprecatedErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("failed to GetServerDetailFromV4: %w", err), &alt)
return
}
v3Server.RouterHostName = &routerHostName
v3Server.RouterPortName = &routerPortName
v3Interfaces, err := tc.V4InterfaceInfoToV3Interfaces(interfaces)
if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("converting to server detail v3: "+err.Error()))
+ api.HandleDeprecatedErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("converting to server detail v3: %w", err), &alt)
return
}
v3Server.ServerInterfaces = &v3Interfaces
v3ServerList = append(v3ServerList, v3Server)
}
- api.RespWriterVals(w, r, inf.Tx.Tx, respVals)(v3ServerList, err)
+ resp = v3ServerList
+ } else {
+ api.WriteRespAlertNotFound(w, r)
return
}
- api.RespWriterVals(w, r, inf.Tx.Tx, respVals)(servers, err)
+
+ api.WriteRespVals(w, r, resp, map[string]interface{}{
+ "alerts": api.CreateDeprecationAlerts(&alt).Alerts,
+ "limit": limit,
+ "orderby": orderBy,
+ "size": size,
+ })
}
+// AddWhereClauseAndQuery adds a WHERE clause to the query given in `q` (does
+// NOT check for existing WHERE clauses or that the end of the string is the
+// proper place to put one!) that limits the query results to those with the
+// given hostname and/or Physical Location ID and, with orderByStr and limitStr
+// appended (in that order), returns the result of querying the given
+// transaction.
+// Use an empty string for the hostname to not filter by hostname, use -1 as
+// physLocationID to not filter by Physical Location.
func AddWhereClauseAndQuery(tx *sql.Tx, q string, hostName string, physLocationID int, orderByStr string, limitStr string) (*sql.Rows, error) {
- if hostName != "" && physLocationID != -1 {
+ if hostName != "" && physLocationID != 0 {
q += ` WHERE server.host_name = $1::text AND server.phys_location = $2::bigint` + orderByStr + limitStr
return tx.Query(q, hostName, physLocationID)
} else if hostName != "" {
q += ` WHERE server.host_name = $1::text` + orderByStr + limitStr
return tx.Query(q, hostName)
- } else if physLocationID != -1 {
+ } else if physLocationID != 0 {
q += ` WHERE server.phys_location = $1::int` + orderByStr + limitStr
return tx.Query(q, physLocationID)
} else {
@@ -158,6 +179,40 @@ func AddWhereClauseAndQuery(tx *sql.Tx, q string, hostName string, physLocationI
}
}
+const dataFetchQuery = `,
+cg.name AS cachegroup,
+cdn.name AS cdn_name,
+ARRAY(select deliveryservice from deliveryservice_server where server = server.id),
+server.domain_name,
+server.guid,
+server.host_name,
+server.https_port,
+server.ilo_ip_address,
+server.ilo_ip_gateway,
+server.ilo_ip_netmask,
+server.ilo_password,
+server.ilo_username,
+(SELECT address FROM ip_address WHERE service_address = true AND family(address) = 4 AND server = server.id) AS service_ip,
+(SELECT address FROM ip_address WHERE service_address = true AND family(address) = 6 AND server = server.id) AS service_ip6,
+(SELECT gateway FROM ip_address WHERE service_address = true AND family(address) = 4 AND server = server.id) AS service_gateway,
+(SELECT gateway FROM ip_address WHERE service_address = true AND family(address) = 6 AND server = server.id) AS service_gateway6,
+(SELECT host(netmask(ip_address.address)) FROM ip_address WHERE service_address = true AND family(address) = 4 AND server = server.id) AS service_netmask,
+(SELECT interface FROM ip_address WHERE service_address = true AND family(address) = 4 AND server = server.id) AS interface_name,
+(SELECT mtu FROM interface WHERE server.id = interface.server AND interface.name = (SELECT interface FROM ip_address WHERE service_address = true AND family(address) = 4 AND server = server.id)) AS interface_mtu,
+server.mgmt_ip_address,
+server.mgmt_ip_gateway,
+server.mgmt_ip_netmask,
+server.offline_reason,
+pl.name as phys_location,
+(SELECT ARRAY_AGG(profile_name) FROM server_profile WHERE server_profile.server=server.id) AS profile_name,
+server.rack,
+st.name as status,
+server.tcp_port,
+t.name as server_type,
+server.xmpp_id,
+server.xmpp_passwd
+`
+
func getDetailServers(tx *sql.Tx, user *auth.CurrentUser, hostName string, physLocationID int, orderBy string, limit int, reqVersion api.Version) ([]tc.ServerDetailV40, error) {
allowedOrderByCols := map[string]string{
"": "",
@@ -192,39 +247,6 @@ func getDetailServers(tx *sql.Tx, user *auth.CurrentUser, hostName string, physL
return nil, errors.New("orderBy '" + orderBy + "' not permitted")
}
- dataFetchQuery := `,
-cg.name AS cachegroup,
-cdn.name AS cdn_name,
-ARRAY(select deliveryservice from deliveryservice_server where server = server.id),
-server.domain_name,
-server.guid,
-server.host_name,
-server.https_port,
-server.ilo_ip_address,
-server.ilo_ip_gateway,
-server.ilo_ip_netmask,
-server.ilo_password,
-server.ilo_username,
-(SELECT address FROM ip_address WHERE service_address = true AND family(address) = 4 AND server = server.id) AS service_ip,
-(SELECT address FROM ip_address WHERE service_address = true AND family(address) = 6 AND server = server.id) AS service_ip6,
-(SELECT gateway FROM ip_address WHERE service_address = true AND family(address) = 4 AND server = server.id) AS service_gateway,
-(SELECT gateway FROM ip_address WHERE service_address = true AND family(address) = 6 AND server = server.id) AS service_gateway6,
-(SELECT host(netmask(ip_address.address)) FROM ip_address WHERE service_address = true AND family(address) = 4 AND server = server.id) AS service_netmask,
-(SELECT interface FROM ip_address WHERE service_address = true AND family(address) = 4 AND server = server.id) AS interface_name,
-(SELECT mtu FROM interface WHERE server.id = interface.server AND interface.name = (SELECT interface FROM ip_address WHERE service_address = true AND family(address) = 4 AND server = server.id)) AS interface_mtu,
-server.mgmt_ip_address,
-server.mgmt_ip_gateway,
-server.mgmt_ip_netmask,
-server.offline_reason,
-pl.name as phys_location,
-(SELECT ARRAY_AGG(profile_name) FROM server_profile WHERE server_profile.server=server.id) AS profile_name,
-server.rack,
-st.name as status,
-server.tcp_port,
-t.name as server_type,
-server.xmpp_id,
-server.xmpp_passwd
-`
queryFormatString := `
SELECT
server.id
@@ -247,42 +269,43 @@ JOIN type t ON server.type = t.id
}
idRows, err := AddWhereClauseAndQuery(tx, fmt.Sprintf(queryFormatString, ""), hostName, physLocationID, orderByStr, limitStr)
if err != nil {
- return nil, errors.New("querying delivery service eligible servers: " + err.Error())
+ return nil, fmt.Errorf("querying delivery service eligible servers: %w", err)
}
- defer idRows.Close()
+ defer log.Close(idRows, "getting IDs for server details names")
var serverIDs []int
for idRows.Next() {
var serverID *int
err := idRows.Scan(&serverID)
if err != nil {
- return nil, errors.New("querying delivery service eligible server ids: " + err.Error())
+ return nil, fmt.Errorf("querying delivery service eligible server ids: %w", err)
}
serverIDs = append(serverIDs, *serverID)
}
serversMap, err := dbhelpers.GetServersInterfaces(serverIDs, tx)
if err != nil {
- return nil, errors.New("unable to get server interfaces: " + err.Error())
+ return nil, fmt.Errorf("unable to get server interfaces: %w", err)
}
rows, err := AddWhereClauseAndQuery(tx, fmt.Sprintf(queryFormatString, dataFetchQuery), hostName, physLocationID, orderByStr, limitStr)
if err != nil {
- return nil, errors.New("Error querying detail servers: " + err.Error())
+ return nil, fmt.Errorf("querying detail servers: %w", err)
}
- defer rows.Close()
+ defer log.Close(rows, "getting server details data")
sIDs := []int{}
servers := []tc.ServerDetailV40{}
- serviceAddress := util.StrPtr("")
- service6Address := util.StrPtr("")
- serviceGateway := util.StrPtr("")
- service6Gateway := util.StrPtr("")
- serviceNetmask := util.StrPtr("")
- serviceInterface := util.StrPtr("")
- serviceMtu := util.StrPtr("")
+ serviceAddress := new(string)
+ service6Address := new(string)
+ serviceGateway := new(string)
+ service6Gateway := new(string)
+ serviceNetmask := new(string)
+ serviceInterface := new(string)
+ serviceMtu := new(string)
for rows.Next() {
s := tc.ServerDetailV40{}
- if err := rows.Scan(&s.ID,
+ err = rows.Scan(
+ &s.ID,
&s.CacheGroup,
&s.CDNName,
pq.Array(&s.DeliveryServiceIDs),
@@ -313,8 +336,10 @@ JOIN type t ON server.type = t.id
&s.TCPPort,
&s.Type,
&s.XMPPID,
- &s.XMPPPasswd); err != nil {
- return nil, errors.New("Error scanning detail server: " + err.Error())
+ &s.XMPPPasswd,
+ )
+ if err != nil {
+ return nil, fmt.Errorf("scanning detail server: %w", err)
}
s.ServerInterfaces = []tc.ServerInterfaceInfoV40{}
if interfacesMap, ok := serversMap[*s.ID]; ok {
@@ -335,16 +360,16 @@ JOIN type t ON server.type = t.id
rows, err = tx.Query(`SELECT serverid, description, val from hwinfo where serverid = ANY($1);`, pq.Array(sIDs))
if err != nil {
- return nil, errors.New("Error querying detail servers hardware info: " + err.Error())
+ return nil, fmt.Errorf("querying detail servers hardware info: %w", err)
}
- defer rows.Close()
+ defer log.Close(rows, "getting hwinfo data")
hwInfos := map[int]map[string]string{}
for rows.Next() {
serverID := 0
desc := ""
val := ""
if err := rows.Scan(&serverID, &desc, &val); err != nil {
- return nil, errors.New("Error scanning detail server hardware info: " + err.Error())
+ return nil, fmt.Errorf("scanning detail server hardware info: %w", err)
}
hwInfo, ok := hwInfos[serverID]
diff --git a/traffic_ops/v3-client/server.go b/traffic_ops/v3-client/server.go
index 13b2fad97c..c7d026c3e6 100644
--- a/traffic_ops/v3-client/server.go
+++ b/traffic_ops/v3-client/server.go
@@ -204,6 +204,10 @@ func (to *Session) GetFirstServer(params *url.Values, header http.Header) (tc.Se
return firstServer, reqInf, err
}
+// GetServerDetailsByHostNameWithHdr retrieves the "details" of all servers with
+// the given hostname.
+// Deprecated: Server "details" as a concept have been removed from the latest
+// version of the API, and clients should use GetServersWithHdr instead.
func (to *Session) GetServerDetailsByHostNameWithHdr(hostName string, header http.Header) ([]tc.ServerDetailV30, toclientlib.ReqInf, error) {
v := url.Values{}
v.Add("hostName", hostName)
diff --git a/traffic_ops/v4-client/server.go b/traffic_ops/v4-client/server.go
index 59d3009488..ab56c42c47 100644
--- a/traffic_ops/v4-client/server.go
+++ b/traffic_ops/v4-client/server.go
@@ -29,9 +29,6 @@ const (
// apiServers is the API version-relative path to the /servers API
// endpoint.
apiServers = "/servers"
- // apiServersDetails is the API version-relative path to the
- // /servers/details API endpoint.
- apiServersDetails = "/servers/details"
)
func needAndCanFetch(id *int, name *string) bool {
@@ -127,14 +124,6 @@ func (to *Session) GetServers(opts RequestOptions) (tc.ServersV4Response, toclie
return data, reqInf, err
}
-// GetServersDetails retrieves the Server Details of the Server with the given
-// (short) Hostname.
-func (to *Session) GetServersDetails(opts RequestOptions) (tc.ServersV4DetailResponse, toclientlib.ReqInf, error) {
- var data tc.ServersV4DetailResponse
- reqInf, err := to.get(apiServersDetails, opts, &data)
- return data, reqInf, err
-}
-
// DeleteServer deletes the Server with the given ID.
func (to *Session) DeleteServer(id int, opts RequestOptions) (tc.Alerts, toclientlib.ReqInf, error) {
route := fmt.Sprintf("%s/%d", apiServers, id)