From 45a3d01213d57595d9c6a3a429fb46d1b0667757 Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Fri, 29 Jul 2022 15:03:01 -0600 Subject: [PATCH 01/17] Added a new route and logic for assigning multiple server capabilities to a server. --- lib/go-tc/server_server_capability.go | 5 ++ .../traffic_ops_golang/routing/routes.go | 3 + .../server/servers_server_capability.go | 85 +++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/lib/go-tc/server_server_capability.go b/lib/go-tc/server_server_capability.go index 6c406bfa2f..ec2df5c188 100644 --- a/lib/go-tc/server_server_capability.go +++ b/lib/go-tc/server_server_capability.go @@ -27,6 +27,11 @@ type ServerServerCapability struct { ServerCapability *string `json:"serverCapability" db:"server_capability"` } +type MultipleServerCapabilities struct { + ServerID *int `json:"serverId" db:"server"` + ServerCapability []string `json:"serverCapability" db:"server_capability"` +} + // ServerServerCapabilitiesResponse is the type of a response from Traffic // Ops to a request made to its /server_server_capabilities. type ServerServerCapabilitiesResponse struct { diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go b/traffic_ops/traffic_ops_golang/routing/routes.go index f5c3b7bcf0..9c324bcb6f 100644 --- a/traffic_ops/traffic_ops_golang/routing/routes.go +++ b/traffic_ops/traffic_ops_golang/routing/routes.go @@ -334,6 +334,9 @@ func Routes(d ServerData) ([]Route, http.Handler, error) { {Version: api.Version{Major: 4, 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: 42931668343}, {Version: api.Version{Major: 4, 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: 40587140583}, + // Assign Multiple Server Capabilities + {Version: api.Version{Major: 4, Minor: 1}, Method: http.MethodPut, Path: `multiple_server_capabilities/{id}$`, Handler: server.AssignMultipleServerCapabilities, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:CREATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 40792419258}, + //Status: CRUD {Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodGet, Path: `statuses/?$`, Handler: api.ReadHandler(&status.TOStatus{}), RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"STATUS:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 42449056563}, {Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodPut, Path: `statuses/{id}$`, Handler: api.UpdateHandler(&status.TOStatus{}), RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"STATUS:UPDATE", "STATUS:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 42079665043}, diff --git a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go index 64291f21cd..9851574715 100644 --- a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go +++ b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go @@ -20,6 +20,7 @@ package server */ import ( + "encoding/json" "errors" "fmt" "net/http" @@ -441,3 +442,87 @@ func getDSTenantIDsByIDs(tx *sqlx.Tx, dsIDs []int64) ([]DSTenant, error) { return dsTenantIDs, nil } + +// AssignMultipleServerCapabilities helps assign multiple server capabilities to a given server +func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { + inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"id"}, []string{"id"}) + tx := inf.Tx.Tx + if userErr != nil || sysErr != nil { + api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr) + return + } + defer inf.Close() + + var msc tc.MultipleServerCapabilities + if err := json.NewDecoder(r.Body).Decode(&msc); err != nil { + api.HandleErr(w, r, tx, http.StatusBadRequest, err, nil) + return + } + + // Check existence prior to checking type + _, exists, err := dbhelpers.GetServerNameFromID(tx, int64(*msc.ServerID)) + if err != nil { + api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, err) + } + if !exists { + userErr := fmt.Errorf("server %v does not exist", *msc.ServerID) + api.HandleErr(w, r, tx, http.StatusNotFound, userErr, nil) + return + } + + // Ensure type is correct + correctType := true + if err := tx.QueryRow(scCheckServerTypeQuery(), msc.ServerID).Scan(&correctType); err != nil { + api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, fmt.Errorf("checking server type: %v", err)) + return + } + if !correctType { + userErr := fmt.Errorf("server %v has an incorrect server type. Server capabilities can only be assigned to EDGE or MID servers", *msc.ServerID) + api.HandleErr(w, r, tx, http.StatusBadRequest, userErr, nil) + return + } + + cdnName, err := dbhelpers.GetCDNNameFromServerID(tx, int64(*msc.ServerID)) + if err != nil { + api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, err) + return + } + + userErr, sysErr, errCode = dbhelpers.CheckIfCurrentUserCanModifyCDN(tx, string(cdnName), inf.User.UserName) + if userErr != nil || sysErr != nil { + api.HandleErr(w, r, tx, errCode, userErr, sysErr) + return + } + + //Delete existing rows from server_server_capability for a given server + _, err = tx.Exec("DELETE FROM server_server_capability ssc WHERE ssc.server=$1", *msc.ServerID) + if err != nil { + useErr, sysErr, statusCode := api.ParseDBError(err) + api.HandleErr(w, r, tx, statusCode, useErr, sysErr) + return + } + + multipleServerCapabilities := make([]string, 0, len(msc.ServerCapability)) + + mscQuery := `WITH inserted AS ( + INSERT INTO server_server_capability + SELECT "server_capability", $2 + FROM UNNEST($1::text[]) AS tmp("server_capability") + RETURNING server_capability + ) + SELECT ARRAY_AGG(server_capability) + FROM ( + SELECT server_capability + FROM inserted + ) AS returned(server_capability)` + + err = tx.QueryRow(mscQuery, pq.Array(msc.ServerCapability), *msc.ServerID).Scan(pq.Array(&multipleServerCapabilities)) + if err != nil { + useErr, sysErr, statusCode := api.ParseDBError(err) + api.HandleErr(w, r, tx, statusCode, useErr, sysErr) + return + } + alerts := tc.CreateAlerts(tc.SuccessLevel, fmt.Sprintf("Multiple Server Capabilities assigned to a server:%d", *msc.ServerID)) + api.WriteAlertsObj(w, r, http.StatusOK, alerts, msc) + return +} From f80cf34163404cf5668eeafe616209be82cb147e Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Mon, 1 Aug 2022 16:53:38 -0600 Subject: [PATCH 02/17] Added tests for assigning multiple server capabilities to a server. --- .../api/v4/serverservercapability_test.go | 40 +++++++++++++++++++ .../traffic_ops_golang/routing/routes.go | 6 +-- traffic_ops/v4-client/endpoints.go | 2 +- .../v4-client/server_server_capabilities.go | 15 ++++++- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/traffic_ops/testing/api/v4/serverservercapability_test.go b/traffic_ops/testing/api/v4/serverservercapability_test.go index 09f90a189a..4aa60be58a 100644 --- a/traffic_ops/testing/api/v4/serverservercapability_test.go +++ b/traffic_ops/testing/api/v4/serverservercapability_test.go @@ -38,6 +38,7 @@ func TestServerServerCapabilities(t *testing.T) { GetDeliveryServiceServersWithCapabilities(t) UpdateTestServerServerCapabilities(t) GetTestPaginationSupportSsc(t) + AssignMultipleTestServerCapabilities(t) DeleteTestServerServerCapabilityWithInvalidData(t) DeleteTestServerServerCapabilitiesForTopologiesValidation(t) }) @@ -310,6 +311,45 @@ func UpdateTestServerServerCapabilities(t *testing.T) { } } +func AssignMultipleTestServerCapabilities(t *testing.T) { + //Get list of server capabilities + resp, _, err := TOSession.GetServerCapabilities(client.RequestOptions{}) + if err != nil { + t.Fatalf("Expected no error, but got: %v - alerts: %+v", err, resp.Alerts) + } + if len(resp.Response) == 0 { + t.Fatal("no server capability in response, quitting") + } + + originalName := resp.Response[0].Name + var multipleSCs []string + multipleSCs = append(multipleSCs, resp.Response[1].Name, resp.Response[2].Name) + + // Get all servers related to original sever capability name + opts := client.NewRequestOptions() + opts.QueryParameters.Set("serverCapability", originalName) + servOrigResp, _, err := TOSession.GetServerServerCapabilities(opts) + if err != nil { + t.Fatalf("cannot get Capability/server associations for Capability '%s': %v alerts: %+v", originalName, err, servOrigResp.Alerts) + } + if len(servOrigResp.Response) == 0 { + t.Fatalf("no servers associated with server capability name: %v", originalName) + } + origServerID := *servOrigResp.Response[3].ServerID + + msc := tc.MultipleServerCapabilities{ + ServerCapability: multipleSCs, + ServerID: &origServerID, + } + _, reqInf, err := TOSession.AssignMultipleServerCapability(msc, client.NewRequestOptions(), origServerID) + if err != nil { + t.Fatalf("unable to assign update multiple server capabilities to server: %d, error: %v", origServerID, err.Error()) + } + if reqInf.StatusCode != http.StatusOK { + t.Fatalf("Expected:%v, got:%v", http.StatusOK, reqInf.StatusCode) + } +} + func DeleteTestServerServerCapabilities(t *testing.T) { // Get Server Capabilities to delete them sscs, _, err := TOSession.GetServerServerCapabilities(client.RequestOptions{}) diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go b/traffic_ops/traffic_ops_golang/routing/routes.go index 9c324bcb6f..064e0e29bb 100644 --- a/traffic_ops/traffic_ops_golang/routing/routes.go +++ b/traffic_ops/traffic_ops_golang/routing/routes.go @@ -131,6 +131,9 @@ func Routes(d ServerData) ([]Route, http.Handler, error) { * 4.x API */ + // Assign Multiple Server Capabilities + {Version: api.Version{Major: 4, Minor: 1}, Method: http.MethodPut, Path: `multiple_server_capabilities/{id}$`, Handler: server.AssignMultipleServerCapabilities, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:CREATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 40792419258}, + // CDNI integration {Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodGet, Path: `OC/FCI/advertisement/?$`, Handler: cdni.GetCapabilities, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"CDNI-CAPACITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 541357729077}, {Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodPut, Path: `OC/CI/configuration/?$`, Handler: cdni.PutConfiguration, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"CDNI-CAPACITY:UPDATE"}, Authenticated: Authenticated, Middlewares: nil, ID: 541357729078}, @@ -334,9 +337,6 @@ func Routes(d ServerData) ([]Route, http.Handler, error) { {Version: api.Version{Major: 4, 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: 42931668343}, {Version: api.Version{Major: 4, 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: 40587140583}, - // Assign Multiple Server Capabilities - {Version: api.Version{Major: 4, Minor: 1}, Method: http.MethodPut, Path: `multiple_server_capabilities/{id}$`, Handler: server.AssignMultipleServerCapabilities, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:CREATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 40792419258}, - //Status: CRUD {Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodGet, Path: `statuses/?$`, Handler: api.ReadHandler(&status.TOStatus{}), RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"STATUS:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 42449056563}, {Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodPut, Path: `statuses/{id}$`, Handler: api.UpdateHandler(&status.TOStatus{}), RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"STATUS:UPDATE", "STATUS:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 42079665043}, diff --git a/traffic_ops/v4-client/endpoints.go b/traffic_ops/v4-client/endpoints.go index fd9478cd1c..4f215ac91a 100644 --- a/traffic_ops/v4-client/endpoints.go +++ b/traffic_ops/v4-client/endpoints.go @@ -22,6 +22,6 @@ package client // Versions are ordered latest-first. func apiVersions() []string { return []string{ - "4.0", + "4.1", } } diff --git a/traffic_ops/v4-client/server_server_capabilities.go b/traffic_ops/v4-client/server_server_capabilities.go index 9cd03733a7..a43de69d09 100644 --- a/traffic_ops/v4-client/server_server_capabilities.go +++ b/traffic_ops/v4-client/server_server_capabilities.go @@ -16,6 +16,7 @@ package client */ import ( + "fmt" "net/url" "strconv" @@ -23,10 +24,12 @@ import ( "github.com/apache/trafficcontrol/traffic_ops/toclientlib" ) -// apiServerServerCapabilities is the API version-relative path to the -// /server_server_capabilities API endpoint. +// apiServerServerCapabilities is the API version-relative path to the /server_server_capabilities API endpoint. const apiServerServerCapabilities = "/server_server_capabilities" +// apiMultipleServerCapabilities is the API version-relative path to the /multiple_server_capabilities API endpoint. +const apiMultipleServerCapabilities = "/multiple_server_capabilities" + // CreateServerServerCapability assigns a Server Capability to a Server. func (to *Session) CreateServerServerCapability(ssc tc.ServerServerCapability, opts RequestOptions) (tc.Alerts, toclientlib.ReqInf, error) { var alerts tc.Alerts @@ -53,3 +56,11 @@ func (to *Session) GetServerServerCapabilities(opts RequestOptions) (tc.ServerSe reqInf, err := to.get(apiServerServerCapabilities, opts, &resp) return resp, reqInf, err } + +// AssignMultipleServerCapability assign multiple server capabilities to a server +func (to *Session) AssignMultipleServerCapability(msc tc.MultipleServerCapabilities, opts RequestOptions, id int) (tc.Alerts, toclientlib.ReqInf, error) { + path := fmt.Sprintf("%s/%d", apiMultipleServerCapabilities, id) + var alerts tc.Alerts + reqInf, err := to.put(path, opts, msc, &alerts) + return alerts, reqInf, err +} From 4a15c2f1366229a3c3a2b0dc382f4bef4ac8c34d Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Mon, 1 Aug 2022 16:56:42 -0600 Subject: [PATCH 03/17] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 253641f88f..b70f23eafa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [unreleased] +- [#6033](https://github.com/apache/trafficcontrol/issues/6033) Added ability to assign multiple server capabilities to a server. ## [7.0.0] - 2022-07-19 ### Added From 7b5366df10822cdd1ce365f13e840b4d39263c2e Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Mon, 1 Aug 2022 17:41:32 -0600 Subject: [PATCH 04/17] Updated test based on latest table driven model --- .../api/v4/server_server_capabilities_test.go | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/traffic_ops/testing/api/v4/server_server_capabilities_test.go b/traffic_ops/testing/api/v4/server_server_capabilities_test.go index 71ca9dc9be..4d72ad1658 100644 --- a/traffic_ops/testing/api/v4/server_server_capabilities_test.go +++ b/traffic_ops/testing/api/v4/server_server_capabilities_test.go @@ -37,6 +37,7 @@ func TestServerServerCapabilities(t *testing.T) { currentTime := time.Now().UTC().Add(-15 * time.Second) tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123) + var multipleSCs []string methodTests := utils.V4TestCase{ "GET": { @@ -147,6 +148,16 @@ func TestServerServerCapabilities(t *testing.T) { Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)), }, }, + "PUT": { + "OK When Multiple Server Capability Assignment": { + ClientSession: TOSession, + RequestBody: map[string]interface{}{ + "serverId": GetServerID(t, "dtrc-mid-04")(), + "serverCapability": append(multipleSCs, "disk", "blah"), + }, + Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)), + }, + }, "DELETE": { "OK when NOT the LAST SERVER of CACHE GROUP of TOPOLOGY DS which has REQUIRED CAPABILITIES": { ClientSession: TOSession, @@ -180,13 +191,18 @@ func TestServerServerCapabilities(t *testing.T) { t.Run(method, func(t *testing.T) { for name, testCase := range testCases { ssc := tc.ServerServerCapability{} + msc := tc.MultipleServerCapabilities{} var serverId int var serverCapability string if testCase.RequestBody != nil { dat, err := json.Marshal(testCase.RequestBody) assert.NoError(t, err, "Error occurred when marshalling request body: %v", err) - err = json.Unmarshal(dat, &ssc) + if method == "PUT" { + err = json.Unmarshal(dat, &msc) + } else { + err = json.Unmarshal(dat, &ssc) + } assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err) } @@ -205,6 +221,13 @@ func TestServerServerCapabilities(t *testing.T) { check(t, reqInf, nil, alerts, err) } }) + case "PUT": + t.Run(name, func(t *testing.T) { + alerts, reqInf, err := testCase.ClientSession.AssignMultipleServerCapability(msc, testCase.RequestOpts, serverId) + for _, check := range testCase.Expectations { + check(t, reqInf, nil, alerts, err) + } + }) case "DELETE": t.Run(name, func(t *testing.T) { if val, ok := testCase.RequestOpts.QueryParameters["serverId"]; ok { From 622fba052c758a330216900bb1183193b37cee27 Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Tue, 2 Aug 2022 16:17:40 -0600 Subject: [PATCH 05/17] Added documentation for new route. --- .../api/v4/multiple_server_capabilities.rst | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 docs/source/api/v4/multiple_server_capabilities.rst diff --git a/docs/source/api/v4/multiple_server_capabilities.rst b/docs/source/api/v4/multiple_server_capabilities.rst new file mode 100644 index 0000000000..1fbe92edb7 --- /dev/null +++ b/docs/source/api/v4/multiple_server_capabilities.rst @@ -0,0 +1,81 @@ +.. +.. +.. 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-multiple_server_capabilities: + +****************************** +``multiple_server_capabilities`` +****************************** + +``PUT`` +======== +Associates a list of :term:`Server Capability` to a server. + +:Auth. Required: Yes +:Roles Required: "admin" or "operations" +:Permissions Required: SERVER:UPDATE, SERVER:CREATE, SERVER:READ, SERVER-CAPABILITY:READ +:Response Type: Object + +Request Structure +----------------- +:serverId: The integral, unique identifier of a server to be associated with a :term:`Server Capability` +:serverCapability: List of :term:`Server Capability`'s name to associate + +.. code-block:: http + :caption: Request Example + + PUT /api/4.1/multiple_server_capabilities/1 HTTP/1.1 + Host: trafficops.infra.ciab.test + User-Agent: curl/7.47.0 + Accept: */* + Cookie: mojolicious=... + Content-Length: 84 + Content-Type: application/json + + { + "serverId": 1, + "serverCapability": ["test", "disk"] + } + +Response Structure +------------------ +:serverId: The integral, unique identifier of the newly associated server +:serverCapability: List of :term:`Server Capability`'s name + +.. 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-Type: application/json + Set-Cookie: mojolicious=...; Path=/; Expires=Mon, 8 Aug 2022 17:40:54 GMT; Max-Age=3600; HttpOnly + Whole-Content-Sha512: eQrl48zWids0kDpfCYmmtYMpegjnFxfOVvlBYxxLSfp7P7p6oWX4uiC+/Cfh2X9i3G+MQ36eH95gukJqOBOGbQ== + X-Server-Name: traffic_ops_golang/ + Date: Mon, 02 Aug 2022 22:15:11 GMT + Content-Length: 157 + + { + "alerts": [{ + "text": "Multiple Server Capabilities assigned to a server:1", + "level": "success" + }], + "response": { + "serverId": 1, + "serverCapability": ["test", "disk"] + } +} From 13f4923b6ce6bb6a8eb20177396de37c8ebc4494 Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Tue, 2 Aug 2022 16:22:30 -0600 Subject: [PATCH 06/17] Fixed spacing. --- .../api/v4/multiple_server_capabilities.rst | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/source/api/v4/multiple_server_capabilities.rst b/docs/source/api/v4/multiple_server_capabilities.rst index 1fbe92edb7..e54dab256a 100644 --- a/docs/source/api/v4/multiple_server_capabilities.rst +++ b/docs/source/api/v4/multiple_server_capabilities.rst @@ -15,9 +15,9 @@ .. _to-api-multiple_server_capabilities: -****************************** +******************************** ``multiple_server_capabilities`` -****************************** +******************************** ``PUT`` ======== @@ -70,12 +70,12 @@ Response Structure Content-Length: 157 { - "alerts": [{ - "text": "Multiple Server Capabilities assigned to a server:1", - "level": "success" - }], - "response": { - "serverId": 1, - "serverCapability": ["test", "disk"] - } -} + "alerts": [{ + "text": "Multiple Server Capabilities assigned to a server:1", + "level": "success" + }], + "response": { + "serverId": 1, + "serverCapability": ["test", "disk"] + } + } From a3766c191b4abe8d3a5b002cf3f3577d23e2fff0 Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Tue, 2 Aug 2022 16:28:35 -0600 Subject: [PATCH 07/17] Fixed spacing. --- docs/source/api/v4/multiple_server_capabilities.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/api/v4/multiple_server_capabilities.rst b/docs/source/api/v4/multiple_server_capabilities.rst index e54dab256a..f7f3fe6c20 100644 --- a/docs/source/api/v4/multiple_server_capabilities.rst +++ b/docs/source/api/v4/multiple_server_capabilities.rst @@ -44,7 +44,7 @@ Request Structure Content-Length: 84 Content-Type: application/json - { + { "serverId": 1, "serverCapability": ["test", "disk"] } @@ -69,7 +69,7 @@ Response Structure Date: Mon, 02 Aug 2022 22:15:11 GMT Content-Length: 157 - { + { "alerts": [{ "text": "Multiple Server Capabilities assigned to a server:1", "level": "success" From 18edd482d0b07e455a78705f40656d67d18c3efa Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Wed, 3 Aug 2022 12:29:54 -0600 Subject: [PATCH 08/17] Updated based on review comments. --- .../api/v4/multiple_server_capabilities.rst | 2 ++ lib/go-tc/server_server_capability.go | 3 ++- .../server/servers_server_capability.go | 16 ++++++++-------- .../v4-client/server_server_capabilities.go | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/source/api/v4/multiple_server_capabilities.rst b/docs/source/api/v4/multiple_server_capabilities.rst index f7f3fe6c20..0e0bd56893 100644 --- a/docs/source/api/v4/multiple_server_capabilities.rst +++ b/docs/source/api/v4/multiple_server_capabilities.rst @@ -19,6 +19,8 @@ ``multiple_server_capabilities`` ******************************** +.. versionadded:: 4.1 + ``PUT`` ======== Associates a list of :term:`Server Capability` to a server. diff --git a/lib/go-tc/server_server_capability.go b/lib/go-tc/server_server_capability.go index ec2df5c188..688116ed46 100644 --- a/lib/go-tc/server_server_capability.go +++ b/lib/go-tc/server_server_capability.go @@ -27,8 +27,9 @@ type ServerServerCapability struct { ServerCapability *string `json:"serverCapability" db:"server_capability"` } +// MultipleServerCapabilities represents an association between a server and list of server capabilities. type MultipleServerCapabilities struct { - ServerID *int `json:"serverId" db:"server"` + ServerID int `json:"serverId" db:"server"` ServerCapability []string `json:"serverCapability" db:"server_capability"` } diff --git a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go index 9851574715..5f8d775b28 100644 --- a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go +++ b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go @@ -460,12 +460,12 @@ func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { } // Check existence prior to checking type - _, exists, err := dbhelpers.GetServerNameFromID(tx, int64(*msc.ServerID)) + _, exists, err := dbhelpers.GetServerNameFromID(tx, int64(msc.ServerID)) if err != nil { api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, err) } if !exists { - userErr := fmt.Errorf("server %v does not exist", *msc.ServerID) + userErr := fmt.Errorf("server %d does not exist", msc.ServerID) api.HandleErr(w, r, tx, http.StatusNotFound, userErr, nil) return } @@ -473,16 +473,16 @@ func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { // Ensure type is correct correctType := true if err := tx.QueryRow(scCheckServerTypeQuery(), msc.ServerID).Scan(&correctType); err != nil { - api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, fmt.Errorf("checking server type: %v", err)) + api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, fmt.Errorf("checking server type: %w", err)) return } if !correctType { - userErr := fmt.Errorf("server %v has an incorrect server type. Server capabilities can only be assigned to EDGE or MID servers", *msc.ServerID) + userErr := fmt.Errorf("server %d has an incorrect server type. Server capabilities can only be assigned to EDGE or MID servers", msc.ServerID) api.HandleErr(w, r, tx, http.StatusBadRequest, userErr, nil) return } - cdnName, err := dbhelpers.GetCDNNameFromServerID(tx, int64(*msc.ServerID)) + cdnName, err := dbhelpers.GetCDNNameFromServerID(tx, int64(msc.ServerID)) if err != nil { api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, err) return @@ -495,7 +495,7 @@ func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { } //Delete existing rows from server_server_capability for a given server - _, err = tx.Exec("DELETE FROM server_server_capability ssc WHERE ssc.server=$1", *msc.ServerID) + _, err = tx.Exec("DELETE FROM server_server_capability ssc WHERE ssc.server=$1", msc.ServerID) if err != nil { useErr, sysErr, statusCode := api.ParseDBError(err) api.HandleErr(w, r, tx, statusCode, useErr, sysErr) @@ -516,13 +516,13 @@ func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { FROM inserted ) AS returned(server_capability)` - err = tx.QueryRow(mscQuery, pq.Array(msc.ServerCapability), *msc.ServerID).Scan(pq.Array(&multipleServerCapabilities)) + err = tx.QueryRow(mscQuery, pq.Array(msc.ServerCapability), msc.ServerID).Scan(pq.Array(&multipleServerCapabilities)) if err != nil { useErr, sysErr, statusCode := api.ParseDBError(err) api.HandleErr(w, r, tx, statusCode, useErr, sysErr) return } - alerts := tc.CreateAlerts(tc.SuccessLevel, fmt.Sprintf("Multiple Server Capabilities assigned to a server:%d", *msc.ServerID)) + alerts := tc.CreateAlerts(tc.SuccessLevel, fmt.Sprintf("Multiple Server Capabilities assigned to a server:%d", msc.ServerID)) api.WriteAlertsObj(w, r, http.StatusOK, alerts, msc) return } diff --git a/traffic_ops/v4-client/server_server_capabilities.go b/traffic_ops/v4-client/server_server_capabilities.go index a43de69d09..a3959890c5 100644 --- a/traffic_ops/v4-client/server_server_capabilities.go +++ b/traffic_ops/v4-client/server_server_capabilities.go @@ -57,7 +57,7 @@ func (to *Session) GetServerServerCapabilities(opts RequestOptions) (tc.ServerSe return resp, reqInf, err } -// AssignMultipleServerCapability assign multiple server capabilities to a server +// AssignMultipleServerCapability assigns multiple server capabilities to a server. func (to *Session) AssignMultipleServerCapability(msc tc.MultipleServerCapabilities, opts RequestOptions, id int) (tc.Alerts, toclientlib.ReqInf, error) { path := fmt.Sprintf("%s/%d", apiMultipleServerCapabilities, id) var alerts tc.Alerts From 6b5982320de3624ae167b8f464eabbbdf423d493 Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Wed, 3 Aug 2022 12:40:37 -0600 Subject: [PATCH 09/17] Updated based on review comments-1. --- traffic_ops/traffic_ops_golang/routing/routes.go | 2 +- .../traffic_ops_golang/server/servers_server_capability.go | 2 +- traffic_ops/v4-client/server_server_capabilities.go | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go b/traffic_ops/traffic_ops_golang/routing/routes.go index 064e0e29bb..61ae1c7f1c 100644 --- a/traffic_ops/traffic_ops_golang/routing/routes.go +++ b/traffic_ops/traffic_ops_golang/routing/routes.go @@ -132,7 +132,7 @@ func Routes(d ServerData) ([]Route, http.Handler, error) { */ // Assign Multiple Server Capabilities - {Version: api.Version{Major: 4, Minor: 1}, Method: http.MethodPut, Path: `multiple_server_capabilities/{id}$`, Handler: server.AssignMultipleServerCapabilities, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:CREATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 40792419258}, + {Version: api.Version{Major: 4, Minor: 1}, Method: http.MethodPut, Path: `multiple_server_capabilities/{id}$`, Handler: server.AssignMultipleServerCapabilities, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 40792419258}, // CDNI integration {Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodGet, Path: `OC/FCI/advertisement/?$`, Handler: cdni.GetCapabilities, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"CDNI-CAPACITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 541357729077}, diff --git a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go index 5f8d775b28..25b0270b62 100644 --- a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go +++ b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go @@ -443,7 +443,7 @@ func getDSTenantIDsByIDs(tx *sqlx.Tx, dsIDs []int64) ([]DSTenant, error) { return dsTenantIDs, nil } -// AssignMultipleServerCapabilities helps assign multiple server capabilities to a given server +// AssignMultipleServerCapabilities helps assign multiple server capabilities to a given server. func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"id"}, []string{"id"}) tx := inf.Tx.Tx diff --git a/traffic_ops/v4-client/server_server_capabilities.go b/traffic_ops/v4-client/server_server_capabilities.go index a3959890c5..0ca9e926dd 100644 --- a/traffic_ops/v4-client/server_server_capabilities.go +++ b/traffic_ops/v4-client/server_server_capabilities.go @@ -24,7 +24,8 @@ import ( "github.com/apache/trafficcontrol/traffic_ops/toclientlib" ) -// apiServerServerCapabilities is the API version-relative path to the /server_server_capabilities API endpoint. +// apiServerServerCapabilities is the API version-relative path to the +// /server_server_capabilities API endpoint. const apiServerServerCapabilities = "/server_server_capabilities" // apiMultipleServerCapabilities is the API version-relative path to the /multiple_server_capabilities API endpoint. From f65bf2f232cd6fad2b8ad90d9df0ce79c934ba5f Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Wed, 3 Aug 2022 16:26:13 -0600 Subject: [PATCH 10/17] Added both API versions to allow client flexibility. --- traffic_ops/v4-client/endpoints.go | 1 + 1 file changed, 1 insertion(+) diff --git a/traffic_ops/v4-client/endpoints.go b/traffic_ops/v4-client/endpoints.go index 4f215ac91a..898537eb1e 100644 --- a/traffic_ops/v4-client/endpoints.go +++ b/traffic_ops/v4-client/endpoints.go @@ -22,6 +22,7 @@ package client // Versions are ordered latest-first. func apiVersions() []string { return []string{ + "4.0", "4.1", } } From f9f969795d0714885467dae78282b0673e3f1609 Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Thu, 4 Aug 2022 09:45:19 -0600 Subject: [PATCH 11/17] Updated order of API versions. --- traffic_ops/v4-client/endpoints.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traffic_ops/v4-client/endpoints.go b/traffic_ops/v4-client/endpoints.go index 898537eb1e..470afe26da 100644 --- a/traffic_ops/v4-client/endpoints.go +++ b/traffic_ops/v4-client/endpoints.go @@ -22,7 +22,7 @@ package client // Versions are ordered latest-first. func apiVersions() []string { return []string{ - "4.0", "4.1", + "4.0", } } From b0fe6358af3363b65f2431974677f8e835e67a7a Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Thu, 4 Aug 2022 11:30:03 -0600 Subject: [PATCH 12/17] Removed `id` parameter. --- .../api/v4/multiple_server_capabilities.rst | 30 +++++++++---------- .../traffic_ops_golang/routing/routes.go | 2 +- .../server/servers_server_capability.go | 6 ++-- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/docs/source/api/v4/multiple_server_capabilities.rst b/docs/source/api/v4/multiple_server_capabilities.rst index 0e0bd56893..71b0f35002 100644 --- a/docs/source/api/v4/multiple_server_capabilities.rst +++ b/docs/source/api/v4/multiple_server_capabilities.rst @@ -38,7 +38,7 @@ Request Structure .. code-block:: http :caption: Request Example - PUT /api/4.1/multiple_server_capabilities/1 HTTP/1.1 + PUT /api/4.1/multiple_server_capabilities/ HTTP/1.1 Host: trafficops.infra.ciab.test User-Agent: curl/7.47.0 Accept: */* @@ -46,10 +46,10 @@ Request Structure Content-Length: 84 Content-Type: application/json - { - "serverId": 1, - "serverCapability": ["test", "disk"] - } + { + "serverId": 1, + "serverCapability": ["test", "disk"] + } Response Structure ------------------ @@ -71,13 +71,13 @@ Response Structure Date: Mon, 02 Aug 2022 22:15:11 GMT Content-Length: 157 - { - "alerts": [{ - "text": "Multiple Server Capabilities assigned to a server:1", - "level": "success" - }], - "response": { - "serverId": 1, - "serverCapability": ["test", "disk"] - } - } + { + "alerts": [{ + "text": "Multiple Server Capabilities assigned to a server:1", + "level": "success" + }], + "response": { + "serverId": 1, + "serverCapability": ["test", "disk"] + } + } diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go b/traffic_ops/traffic_ops_golang/routing/routes.go index 61ae1c7f1c..3bd72b8d32 100644 --- a/traffic_ops/traffic_ops_golang/routing/routes.go +++ b/traffic_ops/traffic_ops_golang/routing/routes.go @@ -132,7 +132,7 @@ func Routes(d ServerData) ([]Route, http.Handler, error) { */ // Assign Multiple Server Capabilities - {Version: api.Version{Major: 4, Minor: 1}, Method: http.MethodPut, Path: `multiple_server_capabilities/{id}$`, Handler: server.AssignMultipleServerCapabilities, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 40792419258}, + {Version: api.Version{Major: 4, Minor: 1}, Method: http.MethodPut, Path: `multiple_server_capabilities/$`, Handler: server.AssignMultipleServerCapabilities, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 40792419258}, // CDNI integration {Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodGet, Path: `OC/FCI/advertisement/?$`, Handler: cdni.GetCapabilities, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"CDNI-CAPACITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 541357729077}, diff --git a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go index 25b0270b62..a9a01d8e51 100644 --- a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go +++ b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go @@ -445,7 +445,7 @@ func getDSTenantIDsByIDs(tx *sqlx.Tx, dsIDs []int64) ([]DSTenant, error) { // AssignMultipleServerCapabilities helps assign multiple server capabilities to a given server. func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { - inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"id"}, []string{"id"}) + inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil) tx := inf.Tx.Tx if userErr != nil || sysErr != nil { api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr) @@ -502,8 +502,6 @@ func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { return } - multipleServerCapabilities := make([]string, 0, len(msc.ServerCapability)) - mscQuery := `WITH inserted AS ( INSERT INTO server_server_capability SELECT "server_capability", $2 @@ -516,7 +514,7 @@ func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { FROM inserted ) AS returned(server_capability)` - err = tx.QueryRow(mscQuery, pq.Array(msc.ServerCapability), msc.ServerID).Scan(pq.Array(&multipleServerCapabilities)) + err = tx.QueryRow(mscQuery, pq.Array(msc.ServerCapability), msc.ServerID).Scan(pq.Array(&msc.ServerCapability)) if err != nil { useErr, sysErr, statusCode := api.ParseDBError(err) api.HandleErr(w, r, tx, statusCode, useErr, sysErr) From af387f8b61dba94405f179966450b336834bb090 Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Thu, 4 Aug 2022 14:18:31 -0600 Subject: [PATCH 13/17] Updated based on another set of review comments. --- docs/source/api/v4/multiple_server_capabilities.rst | 4 ++-- lib/go-tc/server_server_capability.go | 4 ++-- .../traffic_ops_golang/server/servers_server_capability.go | 7 +++++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/source/api/v4/multiple_server_capabilities.rst b/docs/source/api/v4/multiple_server_capabilities.rst index 71b0f35002..93c22e83a2 100644 --- a/docs/source/api/v4/multiple_server_capabilities.rst +++ b/docs/source/api/v4/multiple_server_capabilities.rst @@ -48,7 +48,7 @@ Request Structure { "serverId": 1, - "serverCapability": ["test", "disk"] + "serverCapabilities": ["test", "disk"] } Response Structure @@ -78,6 +78,6 @@ Response Structure }], "response": { "serverId": 1, - "serverCapability": ["test", "disk"] + "serverCapabilities": ["test", "disk"] } } diff --git a/lib/go-tc/server_server_capability.go b/lib/go-tc/server_server_capability.go index 688116ed46..535a95da7f 100644 --- a/lib/go-tc/server_server_capability.go +++ b/lib/go-tc/server_server_capability.go @@ -29,8 +29,8 @@ type ServerServerCapability struct { // MultipleServerCapabilities represents an association between a server and list of server capabilities. type MultipleServerCapabilities struct { - ServerID int `json:"serverId" db:"server"` - ServerCapability []string `json:"serverCapability" db:"server_capability"` + ServerID int `json:"serverId" db:"server"` + ServerCapabilities []string `json:"serverCapabilities" db:"server_capability"` } // ServerServerCapabilitiesResponse is the type of a response from Traffic diff --git a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go index a9a01d8e51..80a6f3d244 100644 --- a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go +++ b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go @@ -502,6 +502,8 @@ func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { return } + multipleServerCapabilities := make([]string, 0, len(msc.ServerCapabilities)) + mscQuery := `WITH inserted AS ( INSERT INTO server_server_capability SELECT "server_capability", $2 @@ -514,13 +516,14 @@ func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { FROM inserted ) AS returned(server_capability)` - err = tx.QueryRow(mscQuery, pq.Array(msc.ServerCapability), msc.ServerID).Scan(pq.Array(&msc.ServerCapability)) + err = tx.QueryRow(mscQuery, pq.Array(msc.ServerCapabilities), msc.ServerID).Scan(pq.Array(&multipleServerCapabilities)) if err != nil { useErr, sysErr, statusCode := api.ParseDBError(err) api.HandleErr(w, r, tx, statusCode, useErr, sysErr) return } - alerts := tc.CreateAlerts(tc.SuccessLevel, fmt.Sprintf("Multiple Server Capabilities assigned to a server:%d", msc.ServerID)) + msc.ServerCapabilities = multipleServerCapabilities + alerts := tc.CreateAlerts(tc.SuccessLevel, fmt.Sprintf("Multiple Server Capabilities assigned to a server")) api.WriteAlertsObj(w, r, http.StatusOK, alerts, msc) return } From 76c9cf84526b6f0af1c6cd3ef0dff4abcd1cbbce Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Thu, 4 Aug 2022 15:50:13 -0600 Subject: [PATCH 14/17] Updated test based on route change --- .../testing/api/v4/server_server_capabilities_test.go | 6 +++--- traffic_ops/traffic_ops_golang/routing/routes.go | 2 +- traffic_ops/v4-client/server_server_capabilities.go | 4 +--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/traffic_ops/testing/api/v4/server_server_capabilities_test.go b/traffic_ops/testing/api/v4/server_server_capabilities_test.go index 4d72ad1658..b7519355c4 100644 --- a/traffic_ops/testing/api/v4/server_server_capabilities_test.go +++ b/traffic_ops/testing/api/v4/server_server_capabilities_test.go @@ -149,11 +149,11 @@ func TestServerServerCapabilities(t *testing.T) { }, }, "PUT": { - "OK When Multiple Server Capability Assignment": { + "OK When Assigned Multiple Server Capabilities": { ClientSession: TOSession, RequestBody: map[string]interface{}{ - "serverId": GetServerID(t, "dtrc-mid-04")(), - "serverCapability": append(multipleSCs, "disk", "blah"), + "serverId": GetServerID(t, "dtrc-mid-04")(), + "serverCapabilities": append(multipleSCs, "disk", "blah"), }, Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)), }, diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go b/traffic_ops/traffic_ops_golang/routing/routes.go index 64fcf8b500..7089c120bf 100644 --- a/traffic_ops/traffic_ops_golang/routing/routes.go +++ b/traffic_ops/traffic_ops_golang/routing/routes.go @@ -132,7 +132,7 @@ func Routes(d ServerData) ([]Route, http.Handler, error) { */ // Assign Multiple Server Capabilities - {Version: api.Version{Major: 4, Minor: 1}, Method: http.MethodPut, Path: `multiple_server_capabilities/$`, Handler: server.AssignMultipleServerCapabilities, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 40792419258}, + {Version: api.Version{Major: 4, Minor: 1}, Method: http.MethodPut, Path: `multiple_server_capabilities/?$`, Handler: server.AssignMultipleServerCapabilities, RequiredPrivLevel: auth.PrivLevelOperations, RequiredPermissions: []string{"SERVER:UPDATE", "SERVER:READ", "SERVER-CAPABILITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 40792419258}, // CDNI integration {Version: api.Version{Major: 4, Minor: 0}, Method: http.MethodGet, Path: `OC/FCI/advertisement/?$`, Handler: cdni.GetCapabilities, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"CDNI-CAPACITY:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 541357729077}, diff --git a/traffic_ops/v4-client/server_server_capabilities.go b/traffic_ops/v4-client/server_server_capabilities.go index 0ca9e926dd..dd17238517 100644 --- a/traffic_ops/v4-client/server_server_capabilities.go +++ b/traffic_ops/v4-client/server_server_capabilities.go @@ -16,7 +16,6 @@ package client */ import ( - "fmt" "net/url" "strconv" @@ -60,8 +59,7 @@ func (to *Session) GetServerServerCapabilities(opts RequestOptions) (tc.ServerSe // AssignMultipleServerCapability assigns multiple server capabilities to a server. func (to *Session) AssignMultipleServerCapability(msc tc.MultipleServerCapabilities, opts RequestOptions, id int) (tc.Alerts, toclientlib.ReqInf, error) { - path := fmt.Sprintf("%s/%d", apiMultipleServerCapabilities, id) var alerts tc.Alerts - reqInf, err := to.put(path, opts, msc, &alerts) + reqInf, err := to.put(apiMultipleServerCapabilities, opts, msc, &alerts) return alerts, reqInf, err } From 8181b518391ea1d31c9e6b2b33c6e48a12c92b0c Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Mon, 8 Aug 2022 09:56:54 -0600 Subject: [PATCH 15/17] updated format. --- .../traffic_ops_golang/server/servers_server_capability.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go index 80a6f3d244..2a085be4dd 100644 --- a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go +++ b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go @@ -523,7 +523,7 @@ func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { return } msc.ServerCapabilities = multipleServerCapabilities - alerts := tc.CreateAlerts(tc.SuccessLevel, fmt.Sprintf("Multiple Server Capabilities assigned to a server")) + alerts := tc.CreateAlerts(tc.SuccessLevel, fmt.Sprint("Multiple Server Capabilities assigned to a server")) api.WriteAlertsObj(w, r, http.StatusOK, alerts, msc) return } From 951772672e0ae84cbaa4c1c0403a6e65eca87ed6 Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Tue, 9 Aug 2022 08:51:31 -0600 Subject: [PATCH 16/17] Revert "updated format." This reverts commit 8181b518391ea1d31c9e6b2b33c6e48a12c92b0c. --- .../traffic_ops_golang/server/servers_server_capability.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go index 2a085be4dd..80a6f3d244 100644 --- a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go +++ b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go @@ -523,7 +523,7 @@ func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { return } msc.ServerCapabilities = multipleServerCapabilities - alerts := tc.CreateAlerts(tc.SuccessLevel, fmt.Sprint("Multiple Server Capabilities assigned to a server")) + alerts := tc.CreateAlerts(tc.SuccessLevel, fmt.Sprintf("Multiple Server Capabilities assigned to a server")) api.WriteAlertsObj(w, r, http.StatusOK, alerts, msc) return } From 139859002082937e835b6359563e29bf36e03163 Mon Sep 17 00:00:00 2001 From: Rima Shah Date: Tue, 9 Aug 2022 08:59:25 -0600 Subject: [PATCH 17/17] removed format and updated docs --- .../api/v4/multiple_server_capabilities.rst | 18 +++++++++--------- .../server/servers_server_capability.go | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/source/api/v4/multiple_server_capabilities.rst b/docs/source/api/v4/multiple_server_capabilities.rst index 93c22e83a2..37f56b1549 100644 --- a/docs/source/api/v4/multiple_server_capabilities.rst +++ b/docs/source/api/v4/multiple_server_capabilities.rst @@ -23,17 +23,17 @@ ``PUT`` ======== -Associates a list of :term:`Server Capability` to a server. +Associates a list of :term:`Server Capability` to a server. The API call replaces all the server capabilities assigned to a server with the ones specified in the serverCapabilities field. :Auth. Required: Yes :Roles Required: "admin" or "operations" -:Permissions Required: SERVER:UPDATE, SERVER:CREATE, SERVER:READ, SERVER-CAPABILITY:READ +:Permissions Required: SERVER:UPDATE, SERVER:READ, SERVER-CAPABILITY:READ :Response Type: Object Request Structure ----------------- -:serverId: The integral, unique identifier of a server to be associated with a :term:`Server Capability` -:serverCapability: List of :term:`Server Capability`'s name to associate +:serverId: The integral, unique identifier of a server to be associated with a :term:`Server Capability` +:serverCapabilities: List of :term:`Server Capability`'s name to associate .. code-block:: http :caption: Request Example @@ -53,8 +53,8 @@ Request Structure Response Structure ------------------ -:serverId: The integral, unique identifier of the newly associated server -:serverCapability: List of :term:`Server Capability`'s name +:serverId: The integral, unique identifier of the newly associated server +:serverCapabilities: List of :term:`Server Capability`'s name .. code-block:: http :caption: Response Example @@ -65,15 +65,15 @@ Response Structure Access-Control-Allow-Methods: POST,GET,OPTIONS,PUT,DELETE Access-Control-Allow-Origin: * Content-Type: application/json - Set-Cookie: mojolicious=...; Path=/; Expires=Mon, 8 Aug 2022 17:40:54 GMT; Max-Age=3600; HttpOnly + Set-Cookie: mojolicious=...; Path=/; Expires=Mon, 8 Aug 2022 22:40:54 GMT; Max-Age=3600; HttpOnly Whole-Content-Sha512: eQrl48zWids0kDpfCYmmtYMpegjnFxfOVvlBYxxLSfp7P7p6oWX4uiC+/Cfh2X9i3G+MQ36eH95gukJqOBOGbQ== X-Server-Name: traffic_ops_golang/ - Date: Mon, 02 Aug 2022 22:15:11 GMT + Date: Mon, 08 Aug 2022 16:15:11 GMT Content-Length: 157 { "alerts": [{ - "text": "Multiple Server Capabilities assigned to a server:1", + "text": "Multiple Server Capabilities assigned to a server", "level": "success" }], "response": { diff --git a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go index 80a6f3d244..21ae31db2a 100644 --- a/traffic_ops/traffic_ops_golang/server/servers_server_capability.go +++ b/traffic_ops/traffic_ops_golang/server/servers_server_capability.go @@ -523,7 +523,7 @@ func AssignMultipleServerCapabilities(w http.ResponseWriter, r *http.Request) { return } msc.ServerCapabilities = multipleServerCapabilities - alerts := tc.CreateAlerts(tc.SuccessLevel, fmt.Sprintf("Multiple Server Capabilities assigned to a server")) + alerts := tc.CreateAlerts(tc.SuccessLevel, "Multiple Server Capabilities assigned to a server") api.WriteAlertsObj(w, r, http.StatusOK, alerts, msc) return }