You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by ra...@apache.org on 2021/05/04 15:55:01 UTC
[trafficcontrol] branch master updated: URL Sig Keys in Postgres
and DELETE methods (#5801)
This is an automated email from the ASF dual-hosted git repository.
rawlin 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 15101a5 URL Sig Keys in Postgres and DELETE methods (#5801)
15101a5 is described below
commit 15101a5bb7e7edf19f1bfc8c30848444c44d1fde
Author: mattjackson220 <33...@users.noreply.github.com>
AuthorDate: Tue May 4 09:54:41 2021 -0600
URL Sig Keys in Postgres and DELETE methods (#5801)
* URL Sig Keys in Postgres and DELETE methods
* updated per comments
* return error for delete
* added API doc for new DELETE
* fixed copy error
* added Changelog entry for URL sign key delete
---
CHANGELOG.md | 1 +
docs/source/api/v4/deliveryservices_id_urlkeys.rst | 33 +++++++
.../v4/deliveryservices_xmlid_xmlid_urlkeys.rst | 33 +++++++
.../testing/api/v4/deliveryservices_test.go | 59 +++++++++++
.../traffic_ops_golang/deliveryservice/urlkey.go | 109 +++++++++++++++++++++
traffic_ops/traffic_ops_golang/routing/routes.go | 2 +
.../trafficvault/backends/disabled/disabled.go | 4 +
.../trafficvault/backends/postgres/postgres.go | 25 ++++-
.../trafficvault/backends/postgres/url_sig_keys.go | 82 ++++++++++++++++
.../trafficvault/backends/riaksvc/dsutil.go | 12 +++
.../trafficvault/backends/riaksvc/riak.go | 4 +
.../trafficvault/trafficvault.go | 3 +
traffic_ops/v4-client/deliveryservice.go | 22 +++++
13 files changed, 387 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d38e85d..e82b7ee 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -37,6 +37,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Add a Federation to the Ansible Dataset Loader
- Added asynchronous status to ACME certificate generation.
- Added headers to Traffic Portal, Traffic Ops, and Traffic Monitor to opt out of tracking users via Google FLoC.
+- `DELETE` request method for `deliveryservices/xmlId/{name}/urlkeys` and `deliveryservices/{id}/urlkeys`.
### Fixed
- [#5690](https://github.com/apache/trafficcontrol/issues/5690) - Fixed github action for added/modified db migration file.
diff --git a/docs/source/api/v4/deliveryservices_id_urlkeys.rst b/docs/source/api/v4/deliveryservices_id_urlkeys.rst
index 3fa07ea..e5e42b4 100644
--- a/docs/source/api/v4/deliveryservices_id_urlkeys.rst
+++ b/docs/source/api/v4/deliveryservices_id_urlkeys.rst
@@ -91,3 +91,36 @@ Response Structure
"key15": "...",
}
}
+
+
+``DELETE``
+==========
+.. seealso:: :ref:`to-api-deliveryservices-xmlid-xmlid-urlkeys`
+
+Deletes URL signing keys for a :term:`Delivery Service`.
+
+:Auth. Required: Yes
+:Roles Required: "admin" or "operations"
+:Response Type: Object
+
+Request Structure
+-----------------
+.. table:: Request Path Parameters
+
+ +------+----------------------------------------------------------------------------------------+
+ | Name | Description |
+ +======+========================================================================================+
+ | id | Filter for the :term:`Delivery Service` identified by this integral, unique identifier |
+ +------+----------------------------------------------------------------------------------------+
+
+Response Structure
+------------------
+.. code-block:: json
+ :caption: Response Example
+
+ {
+ "alerts": [{
+ "level": "success",
+ "text": "Successfully deleted URL Sig keys from Traffic Vault"
+ }]
+ }
diff --git a/docs/source/api/v4/deliveryservices_xmlid_xmlid_urlkeys.rst b/docs/source/api/v4/deliveryservices_xmlid_xmlid_urlkeys.rst
index f50aee9..03dca83 100644
--- a/docs/source/api/v4/deliveryservices_xmlid_xmlid_urlkeys.rst
+++ b/docs/source/api/v4/deliveryservices_xmlid_xmlid_urlkeys.rst
@@ -66,3 +66,36 @@ Response Structure
"key14":"DtXsu8nsw04YhT0kNoKBhu2G3P9WRpQJ",
"key7":"cmKoIIxXGAxUMdCsWvnGLoIMGmNiuT5I"
}}
+
+
+``DELETE``
+==========
+.. seealso:: :ref:`to-api-deliveryservices-id-urlkeys`
+
+Deletes URL signing keys for a :term:`Delivery Service`.
+
+:Auth. Required: Yes
+:Roles Required: "admin" or "operations"
+:Response Type: Object
+
+Request Structure
+-----------------
+.. table:: Request Path Parameters
+
+ +-------+------------------------------------------------------+
+ | Name | Description |
+ +=======+======================================================+
+ | xmlid | The 'xml_id' of the desired :term:`Delivery Service` |
+ +-------+------------------------------------------------------+
+
+Response Structure
+------------------
+.. code-block:: json
+ :caption: Response Example
+
+ {
+ "alerts": [{
+ "level": "success",
+ "text": "Successfully deleted URL Sig keys from Traffic Vault"
+ }]
+ }
diff --git a/traffic_ops/testing/api/v4/deliveryservices_test.go b/traffic_ops/testing/api/v4/deliveryservices_test.go
index 80ced6f..439e7fc 100644
--- a/traffic_ops/testing/api/v4/deliveryservices_test.go
+++ b/traffic_ops/testing/api/v4/deliveryservices_test.go
@@ -44,7 +44,9 @@ func TestDeliveryServices(t *testing.T) {
if includeSystemTests {
SSLDeliveryServiceCDNUpdateTest(t)
+ CreateTestDeliveryServicesURLSigKeys(t)
GetTestDeliveryServicesURLSigKeys(t)
+ DeleteTestDeliveryServicesURLSigKeys(t)
}
GetTestDeliveryServicesIMS(t)
@@ -1374,6 +1376,63 @@ func GetTestDeliveryServicesURLSigKeys(t *testing.T) {
}
}
+func CreateTestDeliveryServicesURLSigKeys(t *testing.T) {
+ if len(testData.DeliveryServices) == 0 {
+ t.Fatal("couldn't get the xml ID of test DS")
+ }
+ firstDS := testData.DeliveryServices[0]
+ if firstDS.XMLID == nil {
+ t.Fatal("couldn't get the xml ID of test DS")
+ }
+
+ _, _, err := TOSession.CreateDeliveryServiceURLSigKeys(*firstDS.XMLID, nil)
+ if err != nil {
+ t.Error("failed to create url sig keys: " + err.Error())
+ }
+
+ firstKeys, _, err := TOSession.GetDeliveryServiceURLSigKeys(*firstDS.XMLID, nil)
+ if err != nil {
+ t.Error("failed to get url sig keys: " + err.Error())
+ }
+ if len(firstKeys) == 0 {
+ t.Errorf("failed to create url sig keys")
+ }
+
+ // Create new keys again and check that they are different
+ _, _, err = TOSession.CreateDeliveryServiceURLSigKeys(*firstDS.XMLID, nil)
+ if err != nil {
+ t.Error("failed to create url sig keys: " + err.Error())
+ }
+
+ secondKeys, _, err := TOSession.GetDeliveryServiceURLSigKeys(*firstDS.XMLID, nil)
+ if err != nil {
+ t.Error("failed to get url sig keys: " + err.Error())
+ }
+ if len(secondKeys) == 0 {
+ t.Errorf("failed to create url sig keys")
+ }
+
+ if secondKeys["key0"] == firstKeys["key0"] {
+ t.Errorf("second create did not generate new url sig keys")
+ }
+}
+
+func DeleteTestDeliveryServicesURLSigKeys(t *testing.T) {
+ if len(testData.DeliveryServices) == 0 {
+ t.Fatal("couldn't get the xml ID of test DS")
+ }
+ firstDS := testData.DeliveryServices[0]
+ if firstDS.XMLID == nil {
+ t.Fatal("couldn't get the xml ID of test DS")
+ }
+
+ _, _, err := TOSession.DeleteDeliveryServiceURLSigKeys(*firstDS.XMLID, nil)
+ if err != nil {
+ t.Error("failed to delete url sig keys: " + err.Error())
+ }
+
+}
+
func GetDeliveryServiceByLogsEnabled(t *testing.T) {
if len(testData.DeliveryServices) > 0 {
firstDS := testData.DeliveryServices[0]
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
index 974d05a..bea441b 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
@@ -33,6 +33,7 @@ import (
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
)
+// GetURLKeysByID returns the URL sig keys for a delivery service identified by the id in the path parameter.
func GetURLKeysByID(w http.ResponseWriter, r *http.Request) {
inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"id"}, []string{"id"})
if userErr != nil || sysErr != nil {
@@ -85,6 +86,7 @@ func GetURLKeysByID(w http.ResponseWriter, r *http.Request) {
api.WriteResp(w, r, keys)
}
+// GetURLKeysByName returns the URL sig keys for a delivery service identified by the xmlId in the path parameter.
func GetURLKeysByName(w http.ResponseWriter, r *http.Request) {
inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"name"}, nil)
if userErr != nil || sysErr != nil {
@@ -129,6 +131,8 @@ func GetURLKeysByName(w http.ResponseWriter, r *http.Request) {
api.WriteResp(w, r, keys)
}
+// CopyURLKeys copies the URL sig keys from a delivery service in the 'copy-name' path parameter
+// to the delivery service in the 'name' path parameter.
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 {
@@ -208,6 +212,7 @@ func CopyURLKeys(w http.ResponseWriter, r *http.Request) {
api.WriteRespAlert(w, r, tc.SuccessLevel, "Successfully copied and stored keys")
}
+// GenerateURLKeys generates new URL sig keys for the delivery service identified by the xmlId in the path parameter.
func GenerateURLKeys(w http.ResponseWriter, r *http.Request) {
inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"name"}, nil)
if userErr != nil || sysErr != nil {
@@ -263,6 +268,7 @@ func GenerateURLKeys(w http.ResponseWriter, r *http.Request) {
api.WriteRespAlert(w, r, tc.SuccessLevel, "Successfully generated and stored keys")
}
+// GenerateURLSigKeys generates new URL sig keys.
func GenerateURLSigKeys() (tc.URLSigKeys, error) {
chars := `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_`
numKeys := 16
@@ -289,3 +295,106 @@ func GenerateURLSigKeys() (tc.URLSigKeys, error) {
}
return keys, nil
}
+
+// DeleteURLKeysByID deletes the URL sig keys for the delivery service identified by the id in the path parameter.
+func DeleteURLKeysByID(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, inf.Tx.Tx, errCode, userErr, sysErr)
+ return
+ }
+ defer inf.Close()
+
+ if !inf.Config.TrafficVaultEnabled {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, userErr, errors.New("deliveryservice.DeleteURLKeysByID: Traffic Vault is not configured"))
+ return
+ }
+
+ dsId := inf.IntParams["id"]
+ ds, ok, err := dbhelpers.GetDSNameFromID(inf.Tx.Tx, dsId)
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("getting delivery service name from ID: "+err.Error()))
+ return
+ }
+ if !ok {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+inf.Params["id"]+" not found"), nil)
+ return
+ }
+
+ dsTenantID, ok, err := getDSTenantIDByID(inf.Tx.Tx, inf.IntParams["id"])
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ }
+ if !ok {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+inf.Params["id"]+" not found"), nil)
+ return
+ }
+ if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ } else if !authorized {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
+ return
+ }
+
+ err = inf.Vault.DeleteURLSigKeys(string(ds), inf.Tx.Tx, r.Context())
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("deleting URL Sig keys from Traffic Vault: "+err.Error()))
+ return
+ }
+ api.CreateChangeLogRawTx(api.ApiChange, "DS: "+string(ds)+", ID: "+strconv.Itoa(dsId)+", ACTION: Deleted URL sig keys", inf.User, inf.Tx.Tx)
+ api.WriteRespAlert(w, r, tc.SuccessLevel, "Successfully deleted URL Sig keys from Traffic Vault")
+}
+
+// DeleteURLKeysByName deletes the URL sig keys for the delivery service identified by the xmlId in the path parameter.
+func DeleteURLKeysByName(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, inf.Tx.Tx, errCode, userErr, sysErr)
+ return
+ }
+ defer inf.Close()
+
+ if !inf.Config.TrafficVaultEnabled {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, userErr, errors.New("deliveryservice.DeleteURLKeysByName: Traffic Vault is not configured"))
+ return
+ }
+
+ ds := tc.DeliveryServiceName(inf.Params["name"])
+
+ dsTenantID, ok, err := getDSTenantIDByName(inf.Tx.Tx, ds)
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ }
+ if !ok {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
+ return
+ }
+ if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ } else if !authorized {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
+ return
+ }
+
+ dsId, ok, err := getDSIDFromName(inf.Tx.Tx, string(ds))
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("deliveryservice.DeleteURLKeysByName: getting DS ID from name "+err.Error()))
+ return
+ } else if !ok {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("no DS with name "+string(ds)), nil)
+ return
+ }
+
+ err = inf.Vault.DeleteURLSigKeys(string(ds), inf.Tx.Tx, r.Context())
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("deleting URL Sig keys from Traffic Vault: "+err.Error()))
+ return
+ }
+
+ api.CreateChangeLogRawTx(api.ApiChange, "DS: "+string(ds)+", ID: "+strconv.Itoa(dsId)+", ACTION: Deleted URL sig keys", inf.User, inf.Tx.Tx)
+ api.WriteRespAlert(w, r, tc.SuccessLevel, "Successfully deleted URL Sig keys from Traffic Vault")
+}
diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go b/traffic_ops/traffic_ops_golang/routing/routes.go
index aaf2bb5..7c44a66 100644
--- a/traffic_ops/traffic_ops_golang/routing/routes.go
+++ b/traffic_ops/traffic_ops_golang/routing/routes.go
@@ -500,7 +500,9 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
{api.Version{Major: 4, Minor: 0}, http.MethodPost, `deliveryservices/xmlId/{name}/urlkeys/copyFromXmlId/{copy-name}/?$`, deliveryservice.CopyURLKeys, auth.PrivLevelOperations, Authenticated, nil, 42625010763},
{api.Version{Major: 4, Minor: 0}, http.MethodPost, `deliveryservices/xmlId/{name}/urlkeys/generate/?$`, deliveryservice.GenerateURLKeys, auth.PrivLevelOperations, Authenticated, nil, 45304828243},
{api.Version{Major: 4, Minor: 0}, http.MethodGet, `deliveryservices/xmlId/{name}/urlkeys/?$`, deliveryservice.GetURLKeysByName, auth.PrivLevelReadOnly, Authenticated, nil, 42027192113},
+ {api.Version{Major: 4, Minor: 0}, http.MethodDelete, `deliveryservices/xmlId/{name}/urlkeys/?$`, deliveryservice.DeleteURLKeysByName, auth.PrivLevelOperations, Authenticated, nil, 42027192114},
{api.Version{Major: 4, Minor: 0}, http.MethodGet, `deliveryservices/{id}/urlkeys/?$`, deliveryservice.GetURLKeysByID, auth.PrivLevelReadOnly, Authenticated, nil, 4931971143},
+ {api.Version{Major: 4, Minor: 0}, http.MethodDelete, `deliveryservices/{id}/urlkeys/?$`, deliveryservice.DeleteURLKeysByID, auth.PrivLevelOperations, Authenticated, nil, 4931971144},
//Delivery service LetsEncrypt
{api.Version{Major: 4, Minor: 0}, http.MethodPost, `deliveryservices/sslkeys/generate/letsencrypt/?$`, deliveryservice.GenerateLetsEncryptCertificates, auth.PrivLevelOperations, Authenticated, nil, 4534390523},
diff --git a/traffic_ops/traffic_ops_golang/trafficvault/backends/disabled/disabled.go b/traffic_ops/traffic_ops_golang/trafficvault/backends/disabled/disabled.go
index 81dda37..d18d68b 100644
--- a/traffic_ops/traffic_ops_golang/trafficvault/backends/disabled/disabled.go
+++ b/traffic_ops/traffic_ops_golang/trafficvault/backends/disabled/disabled.go
@@ -81,6 +81,10 @@ func (d *Disabled) PutURLSigKeys(xmlID string, keys tc.URLSigKeys, tx *sql.Tx, c
return disabledErr
}
+func (d *Disabled) DeleteURLSigKeys(xmlID string, tx *sql.Tx, ctx context.Context) error {
+ return disabledErr
+}
+
func (d *Disabled) GetURISigningKeys(xmlID string, tx *sql.Tx, ctx context.Context) ([]byte, bool, error) {
return nil, false, disabledErr
}
diff --git a/traffic_ops/traffic_ops_golang/trafficvault/backends/postgres/postgres.go b/traffic_ops/traffic_ops_golang/trafficvault/backends/postgres/postgres.go
index 6dea910..9b1a554 100644
--- a/traffic_ops/traffic_ops_golang/trafficvault/backends/postgres/postgres.go
+++ b/traffic_ops/traffic_ops_golang/trafficvault/backends/postgres/postgres.go
@@ -133,11 +133,32 @@ func (p *Postgres) DeleteDNSSECKeys(cdnName string, tx *sql.Tx, ctx context.Cont
}
func (p *Postgres) GetURLSigKeys(xmlID string, tx *sql.Tx, ctx context.Context) (tc.URLSigKeys, bool, error) {
- return tc.URLSigKeys{}, false, notImplementedErr
+ tvTx, dbCtx, cancelFunc, err := p.beginTransaction(ctx)
+ if err != nil {
+ return tc.URLSigKeys{}, false, err
+ }
+ defer p.commitTransaction(tvTx, dbCtx, cancelFunc)
+ return getURLSigKeys(xmlID, tvTx, ctx)
}
func (p *Postgres) PutURLSigKeys(xmlID string, keys tc.URLSigKeys, tx *sql.Tx, ctx context.Context) error {
- return notImplementedErr
+ tvTx, dbCtx, cancelFunc, err := p.beginTransaction(ctx)
+ if err != nil {
+ return err
+ }
+ defer p.commitTransaction(tvTx, dbCtx, cancelFunc)
+
+ return putURLSigKeys(xmlID, tvTx, keys, ctx)
+}
+
+func (p *Postgres) DeleteURLSigKeys(xmlID string, tx *sql.Tx, ctx context.Context) error {
+ tvTx, dbCtx, cancelFunc, err := p.beginTransaction(ctx)
+ if err != nil {
+ return err
+ }
+ defer p.commitTransaction(tvTx, dbCtx, cancelFunc)
+
+ return deleteURLSigKeys(xmlID, tvTx, ctx)
}
func (p *Postgres) GetURISigningKeys(xmlID string, tx *sql.Tx, ctx context.Context) ([]byte, bool, error) {
diff --git a/traffic_ops/traffic_ops_golang/trafficvault/backends/postgres/url_sig_keys.go b/traffic_ops/traffic_ops_golang/trafficvault/backends/postgres/url_sig_keys.go
new file mode 100644
index 0000000..93d88cc
--- /dev/null
+++ b/traffic_ops/traffic_ops_golang/trafficvault/backends/postgres/url_sig_keys.go
@@ -0,0 +1,82 @@
+package postgres
+
+/*
+ * 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 (
+ "context"
+ "database/sql"
+ "encoding/json"
+ "errors"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+
+ "github.com/jmoiron/sqlx"
+)
+
+func getURLSigKeys(xmlID string, tvTx *sqlx.Tx, ctx context.Context) (tc.URLSigKeys, bool, error) {
+ var jsonUrlKeys string
+ if err := tvTx.QueryRow("SELECT data FROM url_sig_key WHERE deliveryservice = $1", xmlID).Scan(&jsonUrlKeys); err != nil {
+ if err == sql.ErrNoRows {
+ return tc.URLSigKeys{}, false, nil
+ }
+ e := checkErrWithContext("Traffic Vault PostgreSQL: executing SELECT URL Sig Keys query", err, ctx.Err())
+ return tc.URLSigKeys{}, false, e
+ }
+
+ urlSignKey := tc.URLSigKeys{}
+ err := json.Unmarshal([]byte(jsonUrlKeys), &urlSignKey)
+ if err != nil {
+ return tc.URLSigKeys{}, false, errors.New("unmarshalling keys: " + err.Error())
+ }
+
+ return urlSignKey, true, nil
+}
+
+func putURLSigKeys(xmlID string, tvTx *sqlx.Tx, keys tc.URLSigKeys, ctx context.Context) error {
+ keyJSON, err := json.Marshal(&keys)
+ if err != nil {
+ return errors.New("marshalling keys: " + err.Error())
+ }
+
+ // Delete old keys first if they exist
+ if err = deleteURLSigKeys(xmlID, tvTx, ctx); err != nil {
+ return err
+ }
+
+ res, err := tvTx.Exec("INSERT INTO url_sig_key (deliveryservice, data) VALUES ($1, $2)", xmlID, keyJSON)
+ if err != nil {
+ e := checkErrWithContext("Traffic Vault PostgreSQL: executing INSERT URL Sig Keys query", err, ctx.Err())
+ return e
+ }
+ if rowsAffected, err := res.RowsAffected(); err != nil {
+ return err
+ } else if rowsAffected == 0 {
+ return errors.New("URL Sign Keys: no keys were inserted")
+ }
+ return nil
+}
+
+func deleteURLSigKeys(xmlID string, tvTx *sqlx.Tx, ctx context.Context) error {
+ if _, err := tvTx.Exec("DELETE FROM url_sig_key WHERE deliveryservice = $1", xmlID); err != nil {
+ e := checkErrWithContext("Traffic Vault PostgreSQL: executing DELETE URL Sig Keys query", err, ctx.Err())
+ return e
+ }
+ return nil
+}
diff --git a/traffic_ops/traffic_ops_golang/trafficvault/backends/riaksvc/dsutil.go b/traffic_ops/traffic_ops_golang/trafficvault/backends/riaksvc/dsutil.go
index 5c951ac..203f9a7 100644
--- a/traffic_ops/traffic_ops_golang/trafficvault/backends/riaksvc/dsutil.go
+++ b/traffic_ops/traffic_ops_golang/trafficvault/backends/riaksvc/dsutil.go
@@ -330,6 +330,18 @@ func putURLSigKeys(tx *sql.Tx, authOpts *riak.AuthOptions, riakPort *uint, ds tc
return err
}
+func deleteURLSigningKeys(tx *sql.Tx, authOpts *riak.AuthOptions, riakPort *uint, ds tc.DeliveryServiceName) error {
+ cluster, err := getPooledCluster(tx, authOpts, riakPort)
+ if err != nil {
+ return errors.New("getting pooled Riak cluster: " + err.Error())
+ }
+ key := getURLSigConfigFileName(ds)
+ if err := deleteObject(key, urlSigKeysBucket, cluster); err != nil {
+ return errors.New("deleting object: " + err.Error())
+ }
+ return nil
+}
+
const sslKeysIndex = "sslkeys"
const cdnSSLKeysLimit = 1000 // TODO: emulates Perl; reevaluate?
diff --git a/traffic_ops/traffic_ops_golang/trafficvault/backends/riaksvc/riak.go b/traffic_ops/traffic_ops_golang/trafficvault/backends/riaksvc/riak.go
index 06069b4..e7fb923 100644
--- a/traffic_ops/traffic_ops_golang/trafficvault/backends/riaksvc/riak.go
+++ b/traffic_ops/traffic_ops_golang/trafficvault/backends/riaksvc/riak.go
@@ -81,6 +81,10 @@ func (r *Riak) PutURLSigKeys(xmlID string, keys tc.URLSigKeys, tx *sql.Tx, ctx c
return putURLSigKeys(tx, &r.cfg.AuthOptions, &r.cfg.Port, tc.DeliveryServiceName(xmlID), keys)
}
+func (r *Riak) DeleteURLSigKeys(xmlID string, tx *sql.Tx, ctx context.Context) error {
+ return deleteURLSigningKeys(tx, &r.cfg.AuthOptions, &r.cfg.Port, tc.DeliveryServiceName(xmlID))
+}
+
func (r *Riak) GetURISigningKeys(xmlID string, tx *sql.Tx, ctx context.Context) ([]byte, bool, error) {
return getURISigningKeys(tx, &r.cfg.AuthOptions, &r.cfg.Port, xmlID)
}
diff --git a/traffic_ops/traffic_ops_golang/trafficvault/trafficvault.go b/traffic_ops/traffic_ops_golang/trafficvault/trafficvault.go
index fb63067..08031d8 100644
--- a/traffic_ops/traffic_ops_golang/trafficvault/trafficvault.go
+++ b/traffic_ops/traffic_ops_golang/trafficvault/trafficvault.go
@@ -69,6 +69,9 @@ type TrafficVault interface {
// PutURLSigKeys stores the given URL sig keys for the delivery service identified by
// the given xmlID.
PutURLSigKeys(xmlID string, keys tc.URLSigKeys, tx *sql.Tx, ctx context.Context) error
+ // DeleteURLSigKeys deletes the URL sig keys for the delivery service identified
+ // by the given xmlID.
+ DeleteURLSigKeys(xmlID string, tx *sql.Tx, ctx context.Context) error
// GetURISigningKeys retrieves the URI signing keys (as raw JSON bytes) for the delivery
// service identified by the given xmlID.
GetURISigningKeys(xmlID string, tx *sql.Tx, ctx context.Context) ([]byte, bool, error)
diff --git a/traffic_ops/v4-client/deliveryservice.go b/traffic_ops/v4-client/deliveryservice.go
index ae6daee..e5887a1 100644
--- a/traffic_ops/v4-client/deliveryservice.go
+++ b/traffic_ops/v4-client/deliveryservice.go
@@ -85,6 +85,12 @@ const (
// (namely the XMLID of the Delivery Service of interest).
APIDeliveryServicesURLSigKeys = APIDeliveryServices + "/xmlId/%s/urlkeys"
+ // APIDeliveryServicesURLSigKeysGenerate is the API path on which Traffic Ops provides
+ // functionality to generate new URL-signing keys used by a Delivery Service identified
+ // by its XMLID. It is intended to be used with fmt.Sprintf to insert its required path parameter
+ // (namely the XMLID of the Delivery Service of interest).
+ APIDeliveryServicesURLSigKeysGenerate = APIDeliveryServices + "/xmlId/%s/urlkeys/generate"
+
// APIDeliveryServicesRegexes is the API path on which Traffic Ops serves Delivery Service
// 'regex' (Regular Expression) information.
APIDeliveryServicesRegexes = "/deliveryservices_regexes"
@@ -329,6 +335,22 @@ func (to *Session) GetDeliveryServiceURLSigKeys(dsName string, header http.Heade
return data.Response, reqInf, nil
}
+// CreateDeliveryServiceURLSigKeys creates new URL-signing keys used by the Delivery Service
+// identified by the XMLID 'dsName'
+func (to *Session) CreateDeliveryServiceURLSigKeys(dsName string, header http.Header) (tc.Alerts, toclientlib.ReqInf, error) {
+ var alerts tc.Alerts
+ reqInf, err := to.post(fmt.Sprintf(APIDeliveryServicesURLSigKeysGenerate, dsName), nil, header, &alerts)
+ return alerts, reqInf, err
+}
+
+// DeleteDeliveryServiceURLSigKeys deletes the URL-signing keys used by the Delivery Service
+// identified by the XMLID 'dsName'
+func (to *Session) DeleteDeliveryServiceURLSigKeys(dsName string, header http.Header) (tc.Alerts, toclientlib.ReqInf, error) {
+ var alerts tc.Alerts
+ reqInf, err := to.del(fmt.Sprintf(APIDeliveryServicesURLSigKeys, dsName), header, &alerts)
+ return alerts, reqInf, err
+}
+
// GetDeliveryServiceURISigningKeys returns the URI-signing keys used by the Delivery Service
// identified by the XMLID 'dsName'. The result is not parsed.
func (to *Session) GetDeliveryServiceURISigningKeys(dsName string, header http.Header) ([]byte, toclientlib.ReqInf, error) {