Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use RFC 3339 for lastUpdated timestamp in /server_server_capabilities #7744

Merged
merged 2 commits into from
Aug 28, 2023
Merged
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
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
Loading