You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by de...@apache.org on 2018/07/05 20:40:12 UTC

[trafficcontrol] 02/02: Add TO Go deliveryservice/users tests

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

dewrich pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git

commit 2cf3457989a525493a03429a23912d7d01137d8c
Author: Robert Butts <ro...@apache.org>
AuthorDate: Thu Jun 28 13:43:22 2018 -0600

    Add TO Go deliveryservice/users tests
---
 lib/go-tc/users.go                                 |  45 +++++
 traffic_ops/client/dsuser.go                       |  60 ++++++
 traffic_ops/client/v13/dsuser.go                   |  60 ++++++
 traffic_ops/client/v13/user.go                     |  46 +++++
 .../testing/api/v13/userdeliveryservices_test.go   | 224 +++++++++++++++++++++
 .../traffic_ops_golang/user/deliveryservices.go    |   9 +-
 6 files changed, 441 insertions(+), 3 deletions(-)

diff --git a/lib/go-tc/users.go b/lib/go-tc/users.go
index 954d399..ea56df6 100644
--- a/lib/go-tc/users.go
+++ b/lib/go-tc/users.go
@@ -19,6 +19,10 @@ package tc
  * under the License.
  */
 
+import (
+	"time"
+)
+
 // UsersResponse ...
 type UsersResponse struct {
 	Response []User `json:"response"`
@@ -45,3 +49,44 @@ type UserCredentials struct {
 	Username string `json:"u"`
 	Password string `json:"p"`
 }
+
+// TODO reconcile APIUser and User
+
+type APIUser struct {
+	AddressLine1     *string    `json:"addressLine1", db:"address_line1"`
+	AddressLine2     *string    `json:"addressLine2" db:"address_line2"`
+	City             *string    `json:"city" db:"city"`
+	Company          *string    `json:"company,omitempty" db:"company"`
+	Country          *string    `json:"country" db:"country"`
+	Email            *string    `json:"email" db:"email"`
+	FullName         *string    `json:"fullName" db:"full_name"`
+	GID              *int       `json:"gid" db:"gid"`
+	ID               *int       `json:"id" db:"id"`
+	LastUpdated      *time.Time `json:"lastUpdated" db:"last_updated"`
+	NewUser          *bool      `json:"newUser" db:"new_user"`
+	PhoneNumber      *string    `json:"phoneNumber" db:"phone_number"`
+	PostalCode       *string    `json:"postalCode" db:"postal_code"`
+	PublicSSHKey     *string    `json:"publicSshKey" db:"public_ssh_key"`
+	RegistrationSent *time.Time `json:"registrationSent" db:"registration_sent"`
+	Role             *int       `json:"role" db:"role"`
+	RoleName         *string    `json:"rolename"`
+	StateOrProvince  *string    `json:"stateOrProvince" db:"state_or_province"`
+	Tenant           *string    `json:"tenant"`
+	TenantID         *int       `json:"tenantId" db:"tenant_id"`
+	UID              *int       `json:"uid" db:"uid"`
+	UserName         *string    `json:"username" db:"username"`
+}
+
+type APIUserPost struct {
+	APIUser
+	ConfirmLocalPassword *string `json:"confirmLocalPassword" db:"confirm_local_passwd"`
+	LocalPassword        *string `json:"localPassword" db:"local_passwd"`
+}
+
+type APIUsersResponse struct {
+	Response []APIUser `json:"response"`
+}
+
+type UserDeliveryServiceDeleteResponse struct {
+	Alerts []Alert `json:"alerts"`
+}
diff --git a/traffic_ops/client/dsuser.go b/traffic_ops/client/dsuser.go
new file mode 100644
index 0000000..1a5a184
--- /dev/null
+++ b/traffic_ops/client/dsuser.go
@@ -0,0 +1,60 @@
+package client
+
+/*
+
+   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.
+*/
+
+import (
+	"encoding/json"
+	"strconv"
+
+	tc "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+// GetUserDeliveryServices gets the delivery services associated with the given user.
+func (to *Session) GetUserDeliveryServices(userID int) (*tc.UserDeliveryServicesResponse, ReqInf, error) {
+	uri := apiBase + `/users/` + strconv.Itoa(userID) + `/deliveryservices`
+	resp := tc.UserDeliveryServicesResponse{}
+	reqInf, err := get(to, uri, &resp)
+	if err != nil {
+		return nil, reqInf, err
+	}
+	return &resp, reqInf, nil
+}
+
+// SetUserDeliveryService associates the given delivery services with the given user.
+func (to *Session) SetDeliveryServiceUser(userID int, dses []int, replace bool) (*tc.UserDeliveryServicePostResponse, error) {
+	uri := apiBase + `/deliveryservice_user`
+	ds := tc.DeliveryServiceUserPost{UserID: &userID, DeliveryServices: &dses, Replace: &replace}
+	jsonReq, err := json.Marshal(ds)
+	if err != nil {
+		return nil, err
+	}
+	resp := tc.UserDeliveryServicePostResponse{}
+	err = post(to, uri, jsonReq, &resp)
+	if err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
+
+// DeleteDeliveryServiceUser deletes the association between the given delivery service and user
+func (to *Session) DeleteDeliveryServiceUser(userID int, dsID int) (*tc.UserDeliveryServiceDeleteResponse, error) {
+	uri := apiBase + `/deliveryservice_user/` + strconv.Itoa(dsID) + `/` + strconv.Itoa(userID)
+	resp := tc.UserDeliveryServiceDeleteResponse{}
+	if err := del(to, uri, &resp); err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
diff --git a/traffic_ops/client/v13/dsuser.go b/traffic_ops/client/v13/dsuser.go
new file mode 100644
index 0000000..01bde1b
--- /dev/null
+++ b/traffic_ops/client/v13/dsuser.go
@@ -0,0 +1,60 @@
+package v13
+
+/*
+
+   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.
+*/
+
+import (
+	"encoding/json"
+	"strconv"
+
+	tc "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+// GetUserDeliveryServices gets the delivery services associated with the given user.
+func (to *Session) GetUserDeliveryServices(userID int) (*tc.UserDeliveryServicesResponse, ReqInf, error) {
+	uri := apiBase + `/users/` + strconv.Itoa(userID) + `/deliveryservices`
+	resp := tc.UserDeliveryServicesResponse{}
+	reqInf, err := get(to, uri, &resp)
+	if err != nil {
+		return nil, reqInf, err
+	}
+	return &resp, reqInf, nil
+}
+
+// SetUserDeliveryService associates the given delivery services with the given user.
+func (to *Session) SetDeliveryServiceUser(userID int, dses []int, replace bool) (*tc.UserDeliveryServicePostResponse, error) {
+	uri := apiBase + `/deliveryservice_user`
+	ds := tc.DeliveryServiceUserPost{UserID: &userID, DeliveryServices: &dses, Replace: &replace}
+	jsonReq, err := json.Marshal(ds)
+	if err != nil {
+		return nil, err
+	}
+	resp := tc.UserDeliveryServicePostResponse{}
+	err = post(to, uri, jsonReq, &resp)
+	if err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
+
+// DeleteDeliveryServiceUser deletes the association between the given delivery service and user
+func (to *Session) DeleteDeliveryServiceUser(userID int, dsID int) (*tc.UserDeliveryServiceDeleteResponse, error) {
+	uri := apiBase + `/deliveryservice_user/` + strconv.Itoa(dsID) + `/` + strconv.Itoa(userID)
+	resp := tc.UserDeliveryServiceDeleteResponse{}
+	if err := del(to, uri, &resp); err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
diff --git a/traffic_ops/client/v13/user.go b/traffic_ops/client/v13/user.go
new file mode 100644
index 0000000..ac8ff5b
--- /dev/null
+++ b/traffic_ops/client/v13/user.go
@@ -0,0 +1,46 @@
+package v13
+
+/*
+
+   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.
+*/
+
+import (
+	"encoding/json"
+
+	tc "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+// Users gets an array of Users.
+// Deprecated: use GetUsers
+func (to *Session) Users() ([]tc.User, error) {
+	us, _, err := to.GetUsers()
+	return us, err
+}
+
+func (to *Session) GetUsers() ([]tc.User, ReqInf, error) {
+	url := "/api/1.2/users.json"
+	resp, remoteAddr, err := to.request("GET", url, nil)
+	reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr: remoteAddr}
+	if err != nil {
+		return nil, reqInf, err
+	}
+	defer resp.Body.Close()
+
+	var data tc.UsersResponse
+	if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
+		return nil, reqInf, err
+	}
+
+	return data.Response, reqInf, nil
+}
diff --git a/traffic_ops/testing/api/v13/userdeliveryservices_test.go b/traffic_ops/testing/api/v13/userdeliveryservices_test.go
new file mode 100644
index 0000000..e6acf4f
--- /dev/null
+++ b/traffic_ops/testing/api/v13/userdeliveryservices_test.go
@@ -0,0 +1,224 @@
+package v13
+
+/*
+
+   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.
+*/
+
+import (
+	"github.com/apache/trafficcontrol/lib/go-log"
+	"testing"
+)
+
+func TestUsersDeliveryServices(t *testing.T) {
+	CreateTestCDNs(t)
+	CreateTestTypes(t)
+	CreateTestProfiles(t)
+	CreateTestStatuses(t)
+	CreateTestDivisions(t)
+	CreateTestRegions(t)
+	CreateTestPhysLocations(t)
+	CreateTestCacheGroups(t)
+	CreateTestServers(t)
+	CreateTestDeliveryServices(t)
+
+	CreateTestUsersDeliveryServices(t)
+	GetTestUsersDeliveryServices(t)
+	DeleteTestUsersDeliveryServices(t)
+
+	DeleteTestDeliveryServices(t)
+	DeleteTestServers(t)
+	DeleteTestCacheGroups(t)
+	DeleteTestPhysLocations(t)
+	DeleteTestRegions(t)
+	DeleteTestDivisions(t)
+	DeleteTestStatuses(t)
+	DeleteTestProfiles(t)
+	DeleteTestTypes(t)
+	DeleteTestCDNs(t)
+}
+
+const TestUsersDeliveryServicesUser = "admin" // TODO make dynamic
+
+func CreateTestUsersDeliveryServices(t *testing.T) {
+	log.Debugln("CreateTestUsersDeliveryServices")
+
+	dses, _, err := TOSession.GetDeliveryServices()
+	if err != nil {
+		t.Fatalf("cannot GET DeliveryServices: %v - %v\n", err, dses)
+	}
+	if len(dses) == 0 {
+		t.Fatalf("no delivery services, must have at least 1 ds to test users_deliveryservices\n")
+	}
+	users, _, err := TOSession.GetUsers()
+	if err != nil {
+		t.Fatalf("cannot GET users: %v\n", err)
+	}
+	if len(users) == 0 {
+		t.Fatalf("no users, must have at least 1 user to test users_deliveryservices\n")
+	}
+
+	dsIDs := []int{}
+	for _, ds := range dses {
+		dsIDs = append(dsIDs, ds.ID)
+	}
+
+	userID := 0
+	foundUser := false
+	for _, user := range users {
+		if user.Username == TestUsersDeliveryServicesUser {
+			userID = user.ID
+			foundUser = true
+			break
+		}
+	}
+	if !foundUser {
+		t.Fatalf("get users expected: %v actual: missing\n", TestUsersDeliveryServicesUser)
+	}
+
+	_, err = TOSession.SetDeliveryServiceUser(userID, dsIDs, true)
+	if err != nil {
+		t.Fatalf("failed to set delivery service users: " + err.Error())
+	}
+
+	userDSes, _, err := TOSession.GetUserDeliveryServices(userID)
+	if err != nil {
+		t.Fatalf("get user delivery services returned error: " + err.Error())
+	}
+
+	if len(userDSes.Response) != len(dsIDs) {
+		t.Fatalf("get user delivery services expected %v actual %v\n", len(dsIDs), len(userDSes.Response))
+	}
+
+	actualDSIDMap := map[int]struct{}{}
+	for _, userDS := range userDSes.Response {
+		if userDS.ID == nil {
+			t.Fatalf("get user delivery services returned a DS with a nil ID\n")
+		}
+		actualDSIDMap[*userDS.ID] = struct{}{}
+	}
+	for _, dsID := range dsIDs {
+		if _, ok := actualDSIDMap[dsID]; !ok {
+			t.Fatalf("get user delivery services expected %v actual %v\n", dsID, "missing")
+		}
+	}
+}
+
+func GetTestUsersDeliveryServices(t *testing.T) {
+	log.Debugln("GetTestUsersDeliveryServices")
+
+	dses, _, err := TOSession.GetDeliveryServices()
+	if err != nil {
+		t.Fatalf("cannot GET DeliveryServices: %v - %v\n", err, dses)
+	}
+	if len(dses) == 0 {
+		t.Fatalf("no delivery services, must have at least 1 ds to test users_deliveryservices\n")
+	}
+	users, _, err := TOSession.GetUsers()
+	if err != nil {
+		t.Fatalf("cannot GET users: %v\n", err)
+	}
+	if len(users) == 0 {
+		t.Fatalf("no users, must have at least 1 user to test users_deliveryservices\n")
+	}
+
+	dsIDs := []int64{}
+	for _, ds := range dses {
+		dsIDs = append(dsIDs, int64(ds.ID))
+	}
+
+	userID := 0
+	foundUser := false
+	for _, user := range users {
+		if user.Username == TestUsersDeliveryServicesUser {
+			userID = user.ID
+			foundUser = true
+			break
+		}
+	}
+	if !foundUser {
+		t.Fatalf("get users expected: %v actual: missing\n", TestUsersDeliveryServicesUser)
+	}
+
+	userDSes, _, err := TOSession.GetUserDeliveryServices(userID)
+	if err != nil {
+		t.Fatalf("get user delivery services returned error: " + err.Error() + "\n")
+	}
+
+	if len(userDSes.Response) != len(dsIDs) {
+		t.Fatalf("get user delivery services expected %v actual %v\n", len(dsIDs), len(userDSes.Response))
+	}
+
+	actualDSIDMap := map[int]struct{}{}
+	for _, userDS := range userDSes.Response {
+		if userDS.ID == nil {
+			t.Fatalf("get user delivery services returned a DS with a nil ID\n")
+		}
+		actualDSIDMap[*userDS.ID] = struct{}{}
+	}
+	for _, dsID := range dsIDs {
+		if _, ok := actualDSIDMap[int(dsID)]; !ok {
+			t.Fatalf("get user delivery services expected %v actual %v\n", dsID, "missing")
+		}
+	}
+}
+
+func DeleteTestUsersDeliveryServices(t *testing.T) {
+	log.Debugln("DeleteTestUsersDeliveryServices")
+
+	users, _, err := TOSession.GetUsers()
+	if err != nil {
+		t.Fatalf("cannot GET users: %v\n", err)
+	}
+	if len(users) == 0 {
+		t.Fatalf("no users, must have at least 1 user to test users_deliveryservices\n")
+	}
+	userID := 0
+	foundUser := false
+	for _, user := range users {
+		if user.Username == TestUsersDeliveryServicesUser {
+			userID = user.ID
+			foundUser = true
+			break
+		}
+	}
+	if !foundUser {
+		t.Fatalf("get users expected: %v actual: missing\n", TestUsersDeliveryServicesUser)
+	}
+
+	dses, _, err := TOSession.GetUserDeliveryServices(userID)
+	if err != nil {
+		t.Fatalf("get user delivery services returned error: " + err.Error())
+	}
+	if len(dses.Response) == 0 {
+		t.Fatalf("get user delivery services expected %v actual %v\n", ">0", "0")
+	}
+
+	for _, ds := range dses.Response {
+		if ds.ID == nil {
+			t.Fatalf("get user delivery services returned ds with nil ID\n")
+		}
+		_, err := TOSession.DeleteDeliveryServiceUser(userID, *ds.ID)
+		if err != nil {
+			t.Fatalf("delete user delivery service returned error: " + err.Error())
+		}
+	}
+
+	dses, _, err = TOSession.GetUserDeliveryServices(userID)
+	if err != nil {
+		t.Fatalf("get user delivery services returned error: " + err.Error())
+	}
+	if len(dses.Response) != 0 {
+		t.Fatalf("get user delivery services after deleting expected %v actual %v\n", "0", len(dses.Response))
+	}
+}
diff --git a/traffic_ops/traffic_ops_golang/user/deliveryservices.go b/traffic_ops/traffic_ops_golang/user/deliveryservices.go
index 509bd57..fbde590 100644
--- a/traffic_ops/traffic_ops_golang/user/deliveryservices.go
+++ b/traffic_ops/traffic_ops_golang/user/deliveryservices.go
@@ -94,7 +94,7 @@ func filterAuthorized(db *sqlx.DB, dses []tc.DeliveryServiceNullableV13, user *a
 		if ds.TenantID == nil {
 			continue
 		}
-		authorized, err := tenant.IsResourceAuthorizedToUser(*ds.TenantID, *user, db)
+		authorized, err := tenant.IsResourceAuthorizedToUser(*ds.TenantID, user, db)
 		if err != nil {
 			return nil, errors.New("checking delivery service tenancy authorization: " + err.Error())
 		}
@@ -112,7 +112,7 @@ func filterAvailableAuthorized(db *sqlx.DB, dses []tc.UserAvailableDS, user *aut
 		if ds.TenantID == nil {
 			continue
 		}
-		authorized, err := tenant.IsResourceAuthorizedToUser(*ds.TenantID, *user, db)
+		authorized, err := tenant.IsResourceAuthorizedToUser(*ds.TenantID, user, db)
 		if err != nil {
 			return nil, errors.New("checking delivery service tenancy authorization: " + err.Error())
 		}
@@ -163,7 +163,10 @@ ds.mid_header_rewrite,
 COALESCE(ds.miss_lat, 0.0),
 COALESCE(ds.miss_long, 0.0),
 ds.multi_site_origin,
-ds.org_server_fqdn,
+(SELECT o.protocol::text || '://' || o.fqdn || rtrim(concat(':', o.port::text), ':')
+  FROM origin o
+  WHERE o.deliveryservice = ds.id
+  AND o.is_primary) as org_server_fqdn,
 ds.origin_shield,
 ds.profile as profileID,
 profile.name as profile_name,