This is an automated email from the ASF dual-hosted git repository.

mitchell852 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 bbd9a7c  Updating the cdn of a server which is already to linked to a 
DS should be rejected (#4701)
bbd9a7c is described below

commit bbd9a7c55c411bf1b71f49b31bb08407d6e32531
Author: Srijeet Chatterjee <[email protected]>
AuthorDate: Tue May 26 09:57:27 2020 -0600

    Updating the cdn of a server which is already to linked to a DS should be 
rejected (#4701)
    
    * Updating the cdn of a server which is already to linked to a DS should be 
rejected
    
    * Changing changelog
---
 CHANGELOG.md                                       |  1 +
 traffic_ops/traffic_ops_golang/server/servers.go   | 18 ++++---
 .../traffic_ops_golang/server/servers_test.go      | 60 ++++++++++++++++++++++
 3 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index a8d34dc..1ad6288 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ The format is based on [Keep a 
Changelog](http://keepachangelog.com/en/1.0.0/).
 - Fixed ORT config generation not using the coalesce_number_v6 Parameter.
 - Removed audit logging from the `POST /api/x/serverchecks` Traffic Ops API 
endpoint in order to reduce audit log spam
 - Fixed audit logging from the `/jobs` APIs to bring them back to the same 
level of information provided by TO-Perl
+- Fixed update procedure of servers, so that if a server is linked to one or 
more delivery services, you cannot change its "cdn".
 
 ### Changed
 - Changed some Traffic Ops Go Client methods to use `DeliveryServiceNullable` 
inputs and outputs.
diff --git a/traffic_ops/traffic_ops_golang/server/servers.go 
b/traffic_ops/traffic_ops_golang/server/servers.go
index 42766c5..1ed7968 100644
--- a/traffic_ops/traffic_ops_golang/server/servers.go
+++ b/traffic_ops/traffic_ops_golang/server/servers.go
@@ -363,22 +363,28 @@ func (s *TOServer) Update() (error, error, int) {
        if s.IP6Address != nil && len(strings.TrimSpace(*s.IP6Address)) == 0 {
                s.IP6Address = nil
        }
-
        // see if type changed
        typeID := -1
-       if err := s.APIInfo().Tx.QueryRow("SELECT type FROM server WHERE id = 
$1", s.ID).Scan(&typeID); err != nil {
+       // see if cdn changed
+       cdnId := -1
+
+       if err := s.APIInfo().Tx.QueryRow("SELECT type, cdn_id FROM server 
WHERE id = $1", s.ID).Scan(&typeID, &cdnId); err != nil {
                if err == sql.ErrNoRows {
                        return errors.New("no server found with this id"), nil, 
http.StatusNotFound
                }
                return nil, fmt.Errorf("getting current server type: %v", err), 
http.StatusInternalServerError
        }
 
+       dsIDs := []int64{}
+       if err := s.APIInfo().Tx.QueryRowx("SELECT ARRAY(SELECT deliveryservice 
FROM deliveryservice_server WHERE server = $1)", s.ID).Scan(pq.Array(&dsIDs)); 
err != nil && err != sql.ErrNoRows {
+               return nil, fmt.Errorf("getting server assigned delivery 
services: %v", err), http.StatusInternalServerError
+       }
+       // Check to see if the user is trying to change the CDN of a server, 
which is already linked with a DS
+       if cdnId != *s.CDNID && len(dsIDs) != 0 {
+               return errors.New("server cdn can not be updated when it is 
currently assigned to delivery services"), nil, http.StatusConflict
+       }
        // If type is changing ensure it isn't assigned to any DSes.
        if typeID != *s.TypeID {
-               dsIDs := []int64{}
-               if err := s.APIInfo().Tx.QueryRowx("SELECT ARRAY(SELECT 
deliveryservice FROM deliveryservice_server WHERE server = $1)", 
s.ID).Scan(pq.Array(&dsIDs)); err != nil && err != sql.ErrNoRows {
-                       return nil, fmt.Errorf("getting server assigned 
delivery services: %v", err), http.StatusInternalServerError
-               }
                if len(dsIDs) != 0 {
                        return errors.New("server type can not be updated when 
it is currently assigned to delivery services"), nil, http.StatusConflict
                }
diff --git a/traffic_ops/traffic_ops_golang/server/servers_test.go 
b/traffic_ops/traffic_ops_golang/server/servers_test.go
index 1e510f6..bd4cc5c 100644
--- a/traffic_ops/traffic_ops_golang/server/servers_test.go
+++ b/traffic_ops/traffic_ops_golang/server/servers_test.go
@@ -20,6 +20,7 @@ package server
  */
 
 import (
+       "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
        "net/http"
        "testing"
        "time"
@@ -96,6 +97,65 @@ func getTestServers() []tc.Server {
        return servers
 }
 
+// Test to make sure that updating the "cdn" of a server already assigned to a 
DS fails
+func TestUpdateServer(t *testing.T) {
+       mockDB, mock, err := sqlmock.New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer mockDB.Close()
+
+       db := sqlx.NewDb(mockDB, "sqlmock")
+       defer db.Close()
+
+       testServers := getTestServers()
+
+       rows := sqlmock.NewRows([]string{"type", "cdn_id"})
+       // note here that the cdnid is 5, which is not the same as the initial 
cdnid of the fist traffic server
+       rows.AddRow(testServers[0].TypeID, 5)
+       // Make it return a list of atleast one associated ds
+       dsrows := sqlmock.NewRows([]string{"array"})
+       dsrows.AddRow("{3}")
+       mock.ExpectBegin()
+       mock.ExpectQuery("SELECT").WillReturnRows(rows)
+       mock.ExpectQuery("SELECT ARRAY").WillReturnRows(dsrows)
+
+       snv := tc.ServerNullableV11{
+               CDNID:            &testServers[0].CDNID,
+               FqdnTime:         time.Time{},
+               TypeID:           &testServers[0].TypeID,
+       }
+       sn := tc.ServerNullable{
+               ServerNullableV11: snv,
+               IPIsService:       nil,
+               IP6IsService:      nil,
+       }
+
+       s := &TOServer {
+               APIInfoImpl:    api.APIInfoImpl{
+                       ReqInfo: &api.APIInfo{
+                               Params:    nil,
+                               IntParams: nil,
+                               User:      nil,
+                               ReqID:     0,
+                               Version:   nil,
+                               Tx:        db.MustBegin(),
+                               Config:    nil,
+                       },
+               },
+               ServerNullable: sn,
+       }
+
+       userErr, _, errCode := s.Update()
+       if errCode != 409 {
+               t.Errorf("Update servers: Expected error code of %v, but got 
%v", 409, errCode)
+       }
+       expectedErr := "server cdn can not be updated when it is currently 
assigned to delivery services"
+       if userErr == nil {
+               t.Errorf("Update expected error: %v, but got no error with 
status: %s", expectedErr, http.StatusText(errCode))
+       }
+}
+
 func TestGetServersByCachegroup(t *testing.T) {
        mockDB, mock, err := sqlmock.New()
        if err != nil {

Reply via email to