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 <r...@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