You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by mi...@apache.org on 2018/07/11 16:31:17 UTC

[trafficcontrol] branch master updated (7e6f0be -> 971485c)

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

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


    from 7e6f0be  added staticdnsentry struct
     new f0ffe7e  Add TO Go deliveryservices/id/urlkeys
     new 525a2de  Add TO Go deliveryservices/xmlid/urlkeys
     new 810816f  Add TO Go deliveryservices/xmlId/copyFromXmlId
     new 971485c  Add TO Go deliveryservices/xmlid/urlkeys/generate

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 lib/go-tc/deliveryservice_ssl_keys.go              |   2 +
 .../deliveryservice/deliveryservicesv12.go         |  13 +
 .../traffic_ops_golang/deliveryservice/urlkey.go   | 326 +++++++++++++++++++++
 traffic_ops/traffic_ops_golang/riaksvc/dsutil.go   |  64 +++-
 traffic_ops/traffic_ops_golang/routes.go           |   4 +
 5 files changed, 397 insertions(+), 12 deletions(-)
 create mode 100644 traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go


[trafficcontrol] 01/04: Add TO Go deliveryservices/id/urlkeys

Posted by mi...@apache.org.
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

commit f0ffe7ec10c85662c3d9570a2ecb49b37869751f
Author: Robert Butts <ro...@apache.org>
AuthorDate: Tue Jun 19 13:59:02 2018 -0600

    Add TO Go deliveryservices/id/urlkeys
---
 lib/go-tc/deliveryservice_ssl_keys.go              |   2 +
 .../traffic_ops_golang/deliveryservice/urlkey.go   | 107 +++++++++++++++++++++
 traffic_ops/traffic_ops_golang/riaksvc/dsutil.go   |  43 ++++++---
 traffic_ops/traffic_ops_golang/routes.go           |   1 +
 4 files changed, 141 insertions(+), 12 deletions(-)

diff --git a/lib/go-tc/deliveryservice_ssl_keys.go b/lib/go-tc/deliveryservice_ssl_keys.go
index 0db1494..1a1a9f1 100644
--- a/lib/go-tc/deliveryservice_ssl_keys.go
+++ b/lib/go-tc/deliveryservice_ssl_keys.go
@@ -185,3 +185,5 @@ func (r CDNDNSSECGenerateReq) Validate(tx *sql.Tx) error {
 	}
 	return nil
 }
+
+type URLSigKeys map[string]string
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
new file mode 100644
index 0000000..9b5d029
--- /dev/null
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
@@ -0,0 +1,107 @@
+package deliveryservice
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 (
+	"database/sql"
+	"errors"
+	"fmt"
+	"net/http"
+
+	"github.com/apache/trafficcontrol/lib/go-tc"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/riaksvc"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
+)
+
+func GetURLKeysByID(w http.ResponseWriter, r *http.Request) {
+	inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"id"}, []string{"id"})
+	if userErr != nil || sysErr != nil {
+		api.HandleErr(w, r, errCode, userErr, sysErr)
+		return
+	}
+	defer inf.Close()
+
+	if inf.Config.RiakEnabled == false {
+		api.HandleErr(w, r, http.StatusInternalServerError, userErr, errors.New("deliveryservice.DeleteSSLKeys: Riak is not configured!"))
+		return
+	}
+
+	ds, ok, err := GetDSNameFromID(inf.Tx.Tx, inf.IntParams["id"])
+	if err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("getting delivery service name from ID: "+err.Error()))
+		return
+	}
+	if !ok {
+		api.HandleErr(w, r, http.StatusNotFound, errors.New("delivery service "+inf.Params["id"]+" not found"), nil)
+		return
+	}
+
+	// TODO create a helper function to check all this in a single line.
+	ok, err = tenant.IsTenancyEnabledTx(inf.Tx.Tx)
+	if err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenancy enabled: "+err.Error()))
+		return
+	}
+	if ok {
+		dsTenantID, ok, err := GetDSTenantIDByIDTx(inf.Tx.Tx, inf.IntParams["id"])
+		if err != nil {
+			api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+			return
+		}
+		if !ok {
+			api.HandleErr(w, r, http.StatusNotFound, errors.New("delivery service "+inf.Params["id"]+" not found"), nil)
+			return
+		}
+		if dsTenantID != nil {
+			if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+				api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+				return
+			} else if !authorized {
+				api.HandleErr(w, r, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
+				return
+			}
+		}
+	}
+
+	keys, ok, err := riaksvc.GetURLSigKeys(inf.Tx.Tx, inf.Config.RiakAuthOptions, ds)
+	if err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("getting URL Sig keys from riak: "+err.Error()))
+		return
+	}
+	if !ok {
+		api.WriteRespAlertObj(w, r, tc.SuccessLevel, "No url sig keys found", struct{}{})
+		return
+	}
+	api.WriteResp(w, r, keys)
+}
+
+// GetDSNameFromID loads the DeliveryService's xml_id from the database, from the ID. Returns whether the delivery service was found, and any error.
+// TODO move somewhere generic
+func GetDSNameFromID(tx *sql.Tx, id int) (tc.DeliveryServiceName, bool, error) {
+	name := tc.DeliveryServiceName("")
+	if err := tx.QueryRow(`SELECT xml_id FROM deliveryservice where id = $1`, id).Scan(&name); err != nil {
+		if err == sql.ErrNoRows {
+			return tc.DeliveryServiceName(""), false, nil
+		}
+		return tc.DeliveryServiceName(""), false, fmt.Errorf("querying xml_id for delivery service ID '%v': %v", id, err)
+	}
+	return name, true, nil
+}
diff --git a/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go b/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
index e6ff6ae..81b5377 100644
--- a/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
+++ b/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
@@ -33,6 +33,7 @@ import (
 const DeliveryServiceSSLKeysBucket = "ssl"
 const DNSSECKeysBucket = "dnssec"
 const DefaultDSSSLKeyVersion = "latest"
+const URLSigKeysBucket = "url_sig_keys"
 
 func MakeDSSSLKeyKey(dsName, version string) string {
 	if version == "" {
@@ -54,7 +55,6 @@ func GetDeliveryServiceSSLKeysObj(xmlID string, version string, tx *sql.Tx, auth
 			return nil // not found
 		}
 		if err := json.Unmarshal(ro[0].Value, &key); err != nil {
-			log.Errorf("failed at unmarshaling sslkey response: %s\n", err)
 			return errors.New("unmarshalling Riak result: " + err.Error())
 		}
 		found = true
@@ -172,34 +172,23 @@ func Ping(tx *sql.Tx, authOpts *riak.AuthOptions) (tc.RiakPingResp, error) {
 func GetDNSSECKeys(cdnName string, tx *sql.Tx, authOpts *riak.AuthOptions) (tc.DNSSECKeys, bool, error) {
 	key := tc.DNSSECKeys{}
 	found := false
-	log.Errorln("riaksvc.GetDNSSECKeys calling")
 	err := WithClusterTx(tx, authOpts, func(cluster StorageCluster) error {
-		log.Errorln("riaksvc.GetDNSSECKeys in WithClusterTx")
 		ro, err := FetchObjectValues(cdnName, DNSSECKeysBucket, cluster)
-		log.Errorln("riaksvc.GetDNSSECKeys fetched object values")
 		if err != nil {
-			log.Errorln("riaksvc.GetDNSSECKeys fetched object values returning err")
 			return err
 		}
 		if len(ro) == 0 {
-			log.Errorln("riaksvc.GetDNSSECKeys returning nil, len(ro) is 0")
 			return nil // not found
 		}
-		log.Errorln("riaksvc.GetDNSSECKeys unmarshalling")
 		if err := json.Unmarshal(ro[0].Value, &key); err != nil {
-			log.Errorln("Unmarshaling Riak dnssec response: " + err.Error())
 			return errors.New("unmarshalling Riak dnssec response: " + err.Error())
 		}
-		log.Errorln("riaksvc.GetDNSSECKeys unmarshalled, found true, returning nil err")
 		found = true
 		return nil
 	})
-	log.Errorln("riaksvc.GetDNSSECKeys out of WithCluster")
 	if err != nil {
-		log.Errorln("riaksvc.GetDNSSECKeys WithCluster err, returning err")
 		return key, false, err
 	}
-	log.Errorln("riaksvc.GetDNSSECKeys returning success")
 	return key, found, nil
 }
 
@@ -269,3 +258,33 @@ func DeleteDSSSLKeys(tx *sql.Tx, authOpts *riak.AuthOptions, ds tc.DeliveryServi
 	}
 	return nil
 }
+
+// GetURLSigConfigFileName returns the filename of the Apache Traffic Server URLSig config file
+// TODO move to ats config directory/file
+func GetURLSigConfigFileName(ds tc.DeliveryServiceName) string {
+	return "url_sig_" + string(ds) + ".config"
+}
+
+func GetURLSigKeys(tx *sql.Tx, authOpts *riak.AuthOptions, ds tc.DeliveryServiceName) (tc.URLSigKeys, bool, error) {
+	val := tc.URLSigKeys{}
+	found := false
+	key := GetURLSigConfigFileName(ds)
+	err := WithClusterTx(tx, authOpts, func(cluster StorageCluster) error {
+		ro, err := FetchObjectValues(key, URLSigKeysBucket, cluster)
+		if err != nil {
+			return err
+		}
+		if len(ro) == 0 {
+			return nil // not found
+		}
+		if err := json.Unmarshal(ro[0].Value, &val); err != nil {
+			return errors.New("unmarshalling Riak response: " + err.Error())
+		}
+		found = true
+		return nil
+	})
+	if err != nil {
+		return val, false, err
+	}
+	return val, found, nil
+}
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index 94ec297..b3f853f 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -369,6 +369,7 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible/?(\.json)?$`, deliveryservice.GetServersEligible, auth.PrivLevelReadOnly, Authenticated, nil},
 
 		{1.1, http.MethodPost, `deliveryservices/sslkeys/generate/?(\.json)?$`, deliveryservice.GenerateSSLKeys, auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodGet, `deliveryservices/{id}/urlkeys/?(\.json)?$`, deliveryservice.GetURLKeysByID, auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `riak/bucket/{bucket}/key/{key}/values/?(\.json)?$`, apiriak.GetBucketKey, auth.PrivLevelAdmin, Authenticated, nil},
 
 		//System


[trafficcontrol] 02/04: Add TO Go deliveryservices/xmlid/urlkeys

Posted by mi...@apache.org.
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

commit 525a2de7b112eb3794fcdee52d48b089a6f4300a
Author: Robert Butts <ro...@apache.org>
AuthorDate: Tue Jun 19 20:45:54 2018 -0600

    Add TO Go deliveryservices/xmlid/urlkeys
---
 .../deliveryservice/deliveryservicesv12.go         | 13 ++++++
 .../traffic_ops_golang/deliveryservice/urlkey.go   | 54 ++++++++++++++++++++++
 traffic_ops/traffic_ops_golang/routes.go           |  1 +
 3 files changed, 68 insertions(+)

diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
index d80b7b1..49dd8a8 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
@@ -114,6 +114,19 @@ func getDSTenantIDByName(tx *sql.Tx, name string) (*int, bool, error) {
 	return tenantID, true, nil
 }
 
+// GetDSTenantIDByNameTx returns the tenant ID, whether the delivery service exists, and any error.
+// Note the id may be nil, even if true is returned, if the delivery service exists but its tenant_id field is null.
+func GetDSTenantIDByNameTx(tx *sql.Tx, ds tc.DeliveryServiceName) (*int, bool, error) {
+	tenantID := (*int)(nil)
+	if err := tx.QueryRow(`SELECT tenant_id FROM deliveryservice where xml_id = $1`, ds).Scan(&tenantID); err != nil {
+		if err == sql.ErrNoRows {
+			return nil, false, nil
+		}
+		return nil, false, fmt.Errorf("querying tenant ID for delivery service name '%v': %v", ds, err)
+	}
+	return tenantID, true, nil
+}
+
 // GetXMLID loads the DeliveryService's xml_id from the database, from the ID. Returns whether the delivery service was found, and any error.
 
 func (ds *TODeliveryServiceV12) GetXMLID(tx *sqlx.Tx) (string, bool, error) {
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
index 9b5d029..aae1cbb 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
@@ -93,6 +93,60 @@ func GetURLKeysByID(w http.ResponseWriter, r *http.Request) {
 	api.WriteResp(w, r, keys)
 }
 
+func GetURLKeysByName(w http.ResponseWriter, r *http.Request) {
+	inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"name"}, nil)
+	if userErr != nil || sysErr != nil {
+		api.HandleErr(w, r, errCode, userErr, sysErr)
+		return
+	}
+	defer inf.Close()
+
+	if inf.Config.RiakEnabled == false {
+		api.HandleErr(w, r, http.StatusInternalServerError, userErr, errors.New("deliveryservice.DeleteSSLKeys: Riak is not configured!"))
+		return
+	}
+
+	ds := tc.DeliveryServiceName(inf.Params["name"])
+
+	// TODO create a helper function to check all this in a single line.
+	ok, err := tenant.IsTenancyEnabledTx(inf.Tx.Tx)
+	if err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenancy enabled: "+err.Error()))
+		return
+	}
+	if ok {
+		dsTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, ds)
+		if err != nil {
+			api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+			return
+		}
+		if !ok {
+			api.HandleErr(w, r, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
+			return
+		}
+		if dsTenantID != nil {
+			if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+				api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+				return
+			} else if !authorized {
+				api.HandleErr(w, r, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
+				return
+			}
+		}
+	}
+
+	keys, ok, err := riaksvc.GetURLSigKeys(inf.Tx.Tx, inf.Config.RiakAuthOptions, ds)
+	if err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("getting URL Sig keys from riak: "+err.Error()))
+		return
+	}
+	if !ok {
+		api.WriteRespAlertObj(w, r, tc.SuccessLevel, "No url sig keys found", struct{}{})
+		return
+	}
+	api.WriteResp(w, r, keys)
+}
+
 // GetDSNameFromID loads the DeliveryService's xml_id from the database, from the ID. Returns whether the delivery service was found, and any error.
 // TODO move somewhere generic
 func GetDSNameFromID(tx *sql.Tx, id int) (tc.DeliveryServiceName, bool, error) {
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index b3f853f..3af2c25 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -369,6 +369,7 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible/?(\.json)?$`, deliveryservice.GetServersEligible, auth.PrivLevelReadOnly, Authenticated, nil},
 
 		{1.1, http.MethodPost, `deliveryservices/sslkeys/generate/?(\.json)?$`, deliveryservice.GenerateSSLKeys, auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodGet, `deliveryservices/xmlId/{name}/urlkeys/?(\.json)?$`, deliveryservice.GetURLKeysByName, auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `deliveryservices/{id}/urlkeys/?(\.json)?$`, deliveryservice.GetURLKeysByID, auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `riak/bucket/{bucket}/key/{key}/values/?(\.json)?$`, apiriak.GetBucketKey, auth.PrivLevelAdmin, Authenticated, nil},
 


[trafficcontrol] 03/04: Add TO Go deliveryservices/xmlId/copyFromXmlId

Posted by mi...@apache.org.
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

commit 810816f3a18f380f1dc0779d62c9b5b7db430446
Author: Robert Butts <ro...@apache.org>
AuthorDate: Tue Jun 19 21:55:45 2018 -0600

    Add TO Go deliveryservices/xmlId/copyFromXmlId
---
 .../traffic_ops_golang/deliveryservice/urlkey.go   | 81 ++++++++++++++++++++++
 traffic_ops/traffic_ops_golang/riaksvc/dsutil.go   | 21 ++++++
 traffic_ops/traffic_ops_golang/routes.go           |  1 +
 3 files changed, 103 insertions(+)

diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
index aae1cbb..4f9f4e2 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
@@ -147,6 +147,87 @@ func GetURLKeysByName(w http.ResponseWriter, r *http.Request) {
 	api.WriteResp(w, r, keys)
 }
 
+func CopyURLKeys(w http.ResponseWriter, r *http.Request) {
+	inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"name", "copy-name"}, nil)
+	if userErr != nil || sysErr != nil {
+		api.HandleErr(w, r, errCode, userErr, sysErr)
+		return
+	}
+	defer inf.Close()
+
+	if inf.Config.RiakEnabled == false {
+		api.HandleErr(w, r, http.StatusInternalServerError, userErr, errors.New("deliveryservice.DeleteSSLKeys: Riak is not configured!"))
+		return
+	}
+
+	ds := tc.DeliveryServiceName(inf.Params["name"])
+	copyDS := tc.DeliveryServiceName(inf.Params["copy-name"])
+
+	// TODO create a helper function to check all this in a single line.
+	ok, err := tenant.IsTenancyEnabledTx(inf.Tx.Tx)
+	if err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenancy enabled: "+err.Error()))
+		return
+	}
+	if ok {
+		dsTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, ds)
+		if err != nil {
+			api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+			return
+		}
+		if !ok {
+			api.HandleErr(w, r, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
+			return
+		}
+		if dsTenantID != nil {
+			if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+				api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+				return
+			} else if !authorized {
+				api.HandleErr(w, r, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
+				return
+			}
+		}
+
+		{
+			copyDSTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, copyDS)
+			if err != nil {
+				api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+				return
+			}
+			if !ok {
+				api.HandleErr(w, r, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
+				return
+			}
+			if copyDSTenantID != nil {
+				if authorized, err := tenant.IsResourceAuthorizedToUserTx(*copyDSTenantID, inf.User, inf.Tx.Tx); err != nil {
+					api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+					return
+				} else if !authorized {
+					api.HandleErr(w, r, http.StatusForbidden, errors.New("not authorized on this copy tenant"), nil)
+					return
+				}
+			}
+		}
+	}
+
+	keys, ok, err := riaksvc.GetURLSigKeys(inf.Tx.Tx, inf.Config.RiakAuthOptions, copyDS)
+	if err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("getting URL Sig keys from riak: "+err.Error()))
+		return
+	}
+	if !ok {
+		api.HandleErr(w, r, http.StatusBadRequest, errors.New("Unable to retrieve keys from Delivery Service '"+string(copyDS)+"'"), nil)
+		return
+	}
+
+	if err := riaksvc.PutURLSigKeys(inf.Tx.Tx, inf.Config.RiakAuthOptions, ds, keys); err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("setting URL Sig keys for '"+string(ds)+" copied from "+string(copyDS)+": "+err.Error()))
+		return
+	}
+	api.WriteRespAlert(w, r, tc.SuccessLevel, "Successfully copied and stored keys")
+}
+
 // GetDSNameFromID loads the DeliveryService's xml_id from the database, from the ID. Returns whether the delivery service was found, and any error.
 // TODO move somewhere generic
 func GetDSNameFromID(tx *sql.Tx, id int) (tc.DeliveryServiceName, bool, error) {
diff --git a/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go b/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
index 81b5377..7c543a4 100644
--- a/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
+++ b/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
@@ -288,3 +288,24 @@ func GetURLSigKeys(tx *sql.Tx, authOpts *riak.AuthOptions, ds tc.DeliveryService
 	}
 	return val, found, nil
 }
+
+func PutURLSigKeys(tx *sql.Tx, authOpts *riak.AuthOptions, ds tc.DeliveryServiceName, keys tc.URLSigKeys) error {
+	keyJSON, err := json.Marshal(&keys)
+	if err != nil {
+		return errors.New("marshalling keys: " + err.Error())
+	}
+	err = WithClusterTx(tx, authOpts, func(cluster StorageCluster) error {
+		obj := &riak.Object{
+			ContentType:     "application/json",
+			Charset:         "utf-8",
+			ContentEncoding: "utf-8",
+			Key:             GetURLSigConfigFileName(ds),
+			Value:           []byte(keyJSON),
+		}
+		if err = SaveObject(obj, URLSigKeysBucket, cluster); err != nil {
+			return errors.New("saving Riak object: " + err.Error())
+		}
+		return nil
+	})
+	return err
+}
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index 3af2c25..3298441 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -369,6 +369,7 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible/?(\.json)?$`, deliveryservice.GetServersEligible, auth.PrivLevelReadOnly, Authenticated, nil},
 
 		{1.1, http.MethodPost, `deliveryservices/sslkeys/generate/?(\.json)?$`, deliveryservice.GenerateSSLKeys, auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `deliveryservices/xmlId/{name}/urlkeys/copyFromXmlId/{copy-name}/?(\.json)?$`, deliveryservice.CopyURLKeys, auth.PrivLevelOperations, Authenticated, nil},
 		{1.1, http.MethodGet, `deliveryservices/xmlId/{name}/urlkeys/?(\.json)?$`, deliveryservice.GetURLKeysByName, auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `deliveryservices/{id}/urlkeys/?(\.json)?$`, deliveryservice.GetURLKeysByID, auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `riak/bucket/{bucket}/key/{key}/values/?(\.json)?$`, apiriak.GetBucketKey, auth.PrivLevelAdmin, Authenticated, nil},


[trafficcontrol] 04/04: Add TO Go deliveryservices/xmlid/urlkeys/generate

Posted by mi...@apache.org.
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

commit 971485c613375ec50cf052005b64d9af53a9c835
Author: Robert Butts <ro...@apache.org>
AuthorDate: Tue Jun 19 22:37:51 2018 -0600

    Add TO Go deliveryservices/xmlid/urlkeys/generate
---
 .../traffic_ops_golang/deliveryservice/urlkey.go   | 84 ++++++++++++++++++++++
 traffic_ops/traffic_ops_golang/routes.go           |  1 +
 2 files changed, 85 insertions(+)

diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
index 4f9f4e2..80f8d3e 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
@@ -20,10 +20,13 @@ package deliveryservice
  */
 
 import (
+	"crypto/rand"
 	"database/sql"
 	"errors"
 	"fmt"
+	"math/big"
 	"net/http"
+	"strconv"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
@@ -240,3 +243,84 @@ func GetDSNameFromID(tx *sql.Tx, id int) (tc.DeliveryServiceName, bool, error) {
 	}
 	return name, true, nil
 }
+
+func GenerateURLKeys(w http.ResponseWriter, r *http.Request) {
+	inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"name"}, nil)
+	if userErr != nil || sysErr != nil {
+		api.HandleErr(w, r, errCode, userErr, sysErr)
+		return
+	}
+	defer inf.Close()
+
+	if inf.Config.RiakEnabled == false {
+		api.HandleErr(w, r, http.StatusInternalServerError, userErr, errors.New("deliveryservice.DeleteSSLKeys: Riak is not configured!"))
+		return
+	}
+
+	ds := tc.DeliveryServiceName(inf.Params["name"])
+
+	// TODO create a helper function to check all this in a single line.
+	ok, err := tenant.IsTenancyEnabledTx(inf.Tx.Tx)
+	if err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenancy enabled: "+err.Error()))
+		return
+	}
+	if ok {
+		dsTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, ds)
+		if err != nil {
+			api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+			return
+		}
+		if !ok {
+			api.HandleErr(w, r, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
+			return
+		}
+		if dsTenantID != nil {
+			if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+				api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+				return
+			} else if !authorized {
+				api.HandleErr(w, r, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
+				return
+			}
+		}
+	}
+
+	keys, err := GenerateURLSigKeys()
+	if err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("generating URL sig keys: "+err.Error()))
+	}
+
+	if err := riaksvc.PutURLSigKeys(inf.Tx.Tx, inf.Config.RiakAuthOptions, ds, keys); err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("setting URL Sig keys for '"+string(ds)+": "+err.Error()))
+		return
+	}
+	api.WriteRespAlert(w, r, tc.SuccessLevel, "Successfully generated and stored keys")
+}
+
+func GenerateURLSigKeys() (tc.URLSigKeys, error) {
+	chars := `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_`
+	numKeys := 16
+	numChars := 32
+	keys := map[string]string{}
+	for i := 0; i < numKeys; i++ {
+		v := ""
+		for i := 0; i < numChars; i++ {
+			bi, err := rand.Int(rand.Reader, big.NewInt(int64(len(chars))))
+			if err != nil {
+				return nil, errors.New("generating crypto rand int: " + err.Error())
+			}
+			if !bi.IsInt64() {
+				return nil, fmt.Errorf("crypto rand int returned non-int64")
+			}
+			i := bi.Int64()
+			if i >= int64(len(chars)) {
+				return nil, fmt.Errorf("crypto rand int returned a number larger than requested")
+			}
+			v += string(chars[int(i)])
+		}
+		key := "key" + strconv.Itoa(i)
+		keys[key] = v
+	}
+	return keys, nil
+}
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index 3298441..7f869bd 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -370,6 +370,7 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 
 		{1.1, http.MethodPost, `deliveryservices/sslkeys/generate/?(\.json)?$`, deliveryservice.GenerateSSLKeys, auth.PrivLevelOperations, Authenticated, nil},
 		{1.1, http.MethodPost, `deliveryservices/xmlId/{name}/urlkeys/copyFromXmlId/{copy-name}/?(\.json)?$`, deliveryservice.CopyURLKeys, auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `deliveryservices/xmlId/{name}/urlkeys/generate/?(\.json)?$`, deliveryservice.GenerateURLKeys, auth.PrivLevelOperations, Authenticated, nil},
 		{1.1, http.MethodGet, `deliveryservices/xmlId/{name}/urlkeys/?(\.json)?$`, deliveryservice.GetURLKeysByName, auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `deliveryservices/{id}/urlkeys/?(\.json)?$`, deliveryservice.GetURLKeysByID, auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `riak/bucket/{bucket}/key/{key}/values/?(\.json)?$`, apiriak.GetBucketKey, auth.PrivLevelAdmin, Authenticated, nil},