Skip to content

Commit

Permalink
Use RFC 3339 for lastUpdated timestamp in /server_server_capabilities (
Browse files Browse the repository at this point in the history
…#7744)

* Use RFC 3339 for lastUpdated timestamp in /server_server_capabilities

* Match function name in Godoc
  • Loading branch information
zrhoffman committed Aug 28, 2023
1 parent 6ca8fda commit 62bd082
Show file tree
Hide file tree
Showing 9 changed files with 510 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- [#7691](https://github.com/apache/trafficcontrol/pull/7691) *Traffic Ops* Fixed `/topologies` v5 APIs to respond with `RFC3339` timestamps.
- [#7413](https://github.com/apache/trafficcontrol/issues/7413) *Traffic Ops* Fixed `/service_category` v5 APIs to respond with `RFC3339` timestamps.
- [#7413](https://github.com/apache/trafficcontrol/issues/7706) *Traffic Ops* Fixed `/statuses` v5 APIs to respond with `RFC3339` timestamps.
- [#7743](https://github.com/apache/trafficcontrol/issues/7743) *Traffic Ops* Fixes /server_server_capabilities apis to respond with RFC3339 date/time format
- [#7730](https://github.com/apache/trafficcontrol/pull/7730) *Traffic Monitor* Fixed the panic seen in TM when `plugin.system_stats.timestamp_ms` appears as float and not string.
- [#4393](https://github.com/apache/trafficcontrol/issues/4393) *Traffic Ops* Fixed the error code and alert structure when TO is queried for a delivery service with no ssl keys.
- [#7623](https://github.com/apache/trafficcontrol/pull/7623) *Traffic Ops* Removed TryIfModifiedSinceQuery from servicecategories.go and reused from ims.go
Expand Down
10 changes: 5 additions & 5 deletions docs/source/api/v5/server_server_capabilities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Response Structure
------------------
:serverHostName: The server's host name
:serverId: The server's integral, unique identifier
:lastUpdated: The date and time at which this association between the server and the :term:`Server Capability` was last updated, in :ref:`non-rfc-datetime`
:lastUpdated: The date and time at which this association between the server and the :term:`Server Capability` was last updated, in :rfc:`3339` format
:serverCapability: The :term:`Server Capability`'s name

.. code-block:: http
Expand All @@ -87,13 +87,13 @@ Response Structure
{
"response": [
{
"lastUpdated": "2019-10-07 22:05:31+00",
"lastUpdated": "2023-08-09T14:25:11.017999Z",
"serverHostName": "atlanta-org-1",
"serverId": 260,
"serverCapability": "ram"
},
{
"lastUpdated": "2019-10-07 22:05:31+00",
"lastUpdated": "2023-08-09T14:25:11.017999Z",
"serverHostName": "atlanta-org-2",
"serverId": 261,
"serverCapability": "disk"
Expand Down Expand Up @@ -136,7 +136,7 @@ Request Structure
Response Structure
------------------
:serverId: The integral, unique identifier of the newly associated server
:lastUpdated: The date and time at which this association between the server and the :term:`Server Capability` was last updated, in :ref:`non-rfc-datetime`
:lastUpdated: The date and time at which this association between the server and the :term:`Server Capability` was last updated, in :rfc:`3339` format
:serverCapability: The :term:`Server Capability`'s name

.. code-block:: http
Expand All @@ -162,7 +162,7 @@ Response Structure
}
],
"response": {
"lastUpdated": "2019-10-07 22:15:11+00",
"lastUpdated": "2023-08-09T14:25:11.017999Z",
"serverId": 1,
"serverCapability": "disk"
}
Expand Down
26 changes: 26 additions & 0 deletions lib/go-tc/server_server_capability.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ package tc
* under the License.
*/

import "time"

// ServerServerCapabilityV5 is a ServerServerCapability as it appears in version 5 of the
// Traffic Ops API - it always points to the highest minor version in APIv5.
type ServerServerCapabilityV5 = ServerServerCapabilityV50

// ServerServerCapabilityV50 represents an association between a server capability and a server.
type ServerServerCapabilityV50 struct {
LastUpdated *time.Time `json:"lastUpdated" db:"last_updated"`
Server *string `json:"serverHostName,omitempty" db:"host_name"`
ServerID *int `json:"serverId" db:"server"`
ServerCapability *string `json:"serverCapability" db:"server_capability"`
}

// ServerServerCapability represents an association between a server capability and a server.
type ServerServerCapability struct {
LastUpdated *TimeNoMod `json:"lastUpdated" db:"last_updated"`
Expand All @@ -35,6 +49,18 @@ type MultipleServersCapabilities struct {
PageType string `json:"pageType"`
}

// ServerServerCapabilitiesResponseV5 is the type of a response from the
// /api/5.x/server_server_capabilities Traffic Ops endpoint.
// It always points to the type for the latest minor version of APIv5.
type ServerServerCapabilitiesResponseV5 = ServerServerCapabilitiesResponseV50

// ServerServerCapabilitiesResponseV50 is the type of a response from Traffic
// Ops to a request made to its /api/5.0/server_server_capabilities.
type ServerServerCapabilitiesResponseV50 struct {
Response []ServerServerCapabilityV5 `json:"response"`
Alerts
}

// ServerServerCapabilitiesResponse is the type of a response from Traffic
// Ops to a request made to its /server_server_capabilities.
type ServerServerCapabilitiesResponse struct {
Expand Down
20 changes: 10 additions & 10 deletions traffic_ops/testing/api/v5/server_server_capabilities_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestServerServerCapabilities(t *testing.T) {
currentTime := time.Now().UTC().Add(-15 * time.Second)
tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)

methodTests := utils.TestCase[client.Session, client.RequestOptions, tc.ServerServerCapability]{
methodTests := utils.TestCase[client.Session, client.RequestOptions, tc.ServerServerCapabilityV5]{
"GET": {
"NOT MODIFIED when NO CHANGES made": {
ClientSession: TOSession,
Expand Down Expand Up @@ -102,45 +102,45 @@ func TestServerServerCapabilities(t *testing.T) {
"POST": {
"BAD REQUEST when ALREADY EXISTS": {
ClientSession: TOSession,
RequestBody: tc.ServerServerCapability{
RequestBody: tc.ServerServerCapabilityV5{
ServerID: util.Ptr(GetServerID(t, "dtrc-mid-01")()),
ServerCapability: util.Ptr("disk"),
},
Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
},
"BAD REQUEST when MISSING SERVER ID": {
ClientSession: TOSession,
RequestBody: tc.ServerServerCapability{
RequestBody: tc.ServerServerCapabilityV5{
Server: util.Ptr("disk"),
},
Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
},
"BAD REQUEST when MISSING SERVER CAPABILITY": {
ClientSession: TOSession,
RequestBody: tc.ServerServerCapability{
RequestBody: tc.ServerServerCapabilityV5{
ServerID: util.Ptr(GetServerID(t, "dtrc-mid-01")()),
},
Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
},
"NOT FOUND when SERVER CAPABILITY DOESNT EXIST": {
ClientSession: TOSession,
RequestBody: tc.ServerServerCapability{
RequestBody: tc.ServerServerCapabilityV5{
ServerID: util.Ptr(GetServerID(t, "dtrc-mid-01")()),
ServerCapability: util.Ptr("bogus"),
},
Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusNotFound)),
},
"NOT FOUND when SERVER DOESNT EXIST": {
ClientSession: TOSession,
RequestBody: tc.ServerServerCapability{
RequestBody: tc.ServerServerCapabilityV5{
ServerID: util.Ptr(99999999),
ServerCapability: util.Ptr("bogus"),
},
Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusNotFound)),
},
"BAD REQUEST when SERVER TYPE NOT EDGE or MID": {
ClientSession: TOSession,
RequestBody: tc.ServerServerCapability{
RequestBody: tc.ServerServerCapabilityV5{
ServerID: util.Ptr(GetServerID(t, "trafficvault")()),
ServerCapability: util.Ptr("bogus"),
},
Expand Down Expand Up @@ -225,7 +225,7 @@ func TestServerServerCapabilities(t *testing.T) {
func validateServerServerCapabilitiesFields(expectedResp map[string]interface{}) utils.CkReqFunc {
return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
assert.RequireNotNil(t, resp, "Expected Server Server Capabilities response to not be nil.")
serverServerCapabilityResponse := resp.([]tc.ServerServerCapability)
serverServerCapabilityResponse := resp.([]tc.ServerServerCapabilityV5)
for field, expected := range expectedResp {
for _, serverServerCapability := range serverServerCapabilityResponse {
switch field {
Expand Down Expand Up @@ -261,7 +261,7 @@ func validateServerServerCapabilitiesSort() utils.CkReqFunc {
return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, alerts tc.Alerts, _ error) {
assert.RequireNotNil(t, resp, "Expected Server Server Capabilities response to not be nil.")
var serverNames []string
serverServerCapabilityResponse := resp.([]tc.ServerServerCapability)
serverServerCapabilityResponse := resp.([]tc.ServerServerCapabilityV5)
for _, serverServerCapability := range serverServerCapabilityResponse {
assert.RequireNotNil(t, serverServerCapability.Server, "Expected Server to not be nil.")
serverNames = append(serverNames, *serverServerCapability.Server)
Expand All @@ -272,7 +272,7 @@ func validateServerServerCapabilitiesSort() utils.CkReqFunc {

func validateServerServerCapabilitiesPagination(paginationParam string) utils.CkReqFunc {
return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
paginationResp := resp.([]tc.ServerServerCapability)
paginationResp := resp.([]tc.ServerServerCapabilityV5)

opts := client.NewRequestOptions()
opts.QueryParameters.Set("orderby", "serverId")
Expand Down
2 changes: 1 addition & 1 deletion traffic_ops/testing/api/v5/traffic_control_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type TrafficControl struct {
Regions []tc.RegionV5 `json:"regions"`
Roles []tc.RoleV4 `json:"roles"`
Servers []tc.ServerV5 `json:"servers"`
ServerServerCapabilities []tc.ServerServerCapability `json:"serverServerCapabilities"`
ServerServerCapabilities []tc.ServerServerCapabilityV5 `json:"serverServerCapabilities"`
ServerCapabilities []tc.ServerCapabilityV5 `json:"serverCapabilities"`
ServiceCategories []tc.ServiceCategoryV5 `json:"serviceCategories"`
Statuses []tc.StatusV5 `json:"statuses"`
Expand Down
6 changes: 3 additions & 3 deletions traffic_ops/traffic_ops_golang/routing/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,9 @@ func Routes(d ServerData) ([]Route, http.Handler, error) {
{Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodDelete, Path: `multiple_servers_capabilities/?$`, Handler: server.DeleteMultipleServersCapabilities, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:READ", "SERVER:DELETE", "SERVER-CAPABILITY:READ", "SERVER-CAPABILITY:DELETE"}, Authenticated: Authenticated, Middlewares: nil, ID: 407924192781},

//Server Server Capabilities: CRUD
{Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodGet, Path: `server_server_capabilities/?$`, Handler: api.ReadHandler(&server.TOServerServerCapability{}), RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 480023188931},
{Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodPost, Path: `server_server_capabilities/?$`, Handler: api.CreateHandler(&server.TOServerServerCapability{}), RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 429316683431},
{Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodDelete, Path: `server_server_capabilities/?$`, Handler: api.DeleteHandler(&server.TOServerServerCapability{}), RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 405871405831},
{Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodGet, Path: `server_server_capabilities/?$`, Handler: api.ReadHandler(&server.TOServerServerCapabilityV5{}), RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 480023188931},
{Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodPost, Path: `server_server_capabilities/?$`, Handler: api.CreateHandler(&server.TOServerServerCapabilityV5{}), RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 429316683431},
{Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodDelete, Path: `server_server_capabilities/?$`, Handler: api.DeleteHandler(&server.TOServerServerCapabilityV5{}), RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 405871405831},

//Status: CRUD
{Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodGet, Path: `statuses/?$`, Handler: api.ReadHandler(&status.TOStatusV5{}), RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"STATUS:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 424490565631},
Expand Down

0 comments on commit 62bd082

Please sign in to comment.