You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by el...@apache.org on 2018/10/29 15:36:56 UTC
[trafficcontrol] branch master updated (84253b2 -> 2025541)
This is an automated email from the ASF dual-hosted git repository.
elsloo pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git.
from 84253b2 Updated README
new 73f47fc Add TO cdn/ksk/generate endpoint
new 2025541 Add docs for cdns/dnsseckeys/ksk/generate
The 2 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:
docs/source/api/index.rst | 1 +
docs/source/api/v14/cdn.rst | 66 +++++++++
docs/source/api/{v13 => v14}/index.rst | 8 +-
lib/go-tc/deliveryservice_ssl_keys.go | 27 ++++
traffic_ops/traffic_ops_golang/cdn/genksk.go | 200 +++++++++++++++++++++++++++
traffic_ops/traffic_ops_golang/routes.go | 2 +
6 files changed, 299 insertions(+), 5 deletions(-)
create mode 100644 docs/source/api/v14/cdn.rst
copy docs/source/api/{v13 => v14}/index.rst (88%)
create mode 100644 traffic_ops/traffic_ops_golang/cdn/genksk.go
[trafficcontrol] 01/02: Add TO cdn/ksk/generate endpoint
Posted by el...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
elsloo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
commit 73f47fc4dc5b71ad09e6224c1c6c013b84668429
Author: Robert Butts <ro...@apache.org>
AuthorDate: Thu Oct 4 08:34:22 2018 -0600
Add TO cdn/ksk/generate endpoint
This adds an API endpoint for what is currently only in the old Perl
UI: regenerating CDN KSK DNSSEC keys.
---
lib/go-tc/deliveryservice_ssl_keys.go | 27 ++++
traffic_ops/traffic_ops_golang/cdn/genksk.go | 200 +++++++++++++++++++++++++++
traffic_ops/traffic_ops_golang/routes.go | 2 +
3 files changed, 229 insertions(+)
diff --git a/lib/go-tc/deliveryservice_ssl_keys.go b/lib/go-tc/deliveryservice_ssl_keys.go
index e9d0ac5..3c7dc06 100644
--- a/lib/go-tc/deliveryservice_ssl_keys.go
+++ b/lib/go-tc/deliveryservice_ssl_keys.go
@@ -28,6 +28,8 @@ import (
const DNSSECKSKType = "ksk"
const DNSSECZSKType = "zsk"
const DNSSECKeyStatusNew = "new"
+const DNSSECKeyStatusExpired = "expired"
+const DNSSECStatusExisting = "existing"
// DeliveryServiceSSLKeysResponse ...
type DeliveryServiceSSLKeysResponse struct {
@@ -277,3 +279,28 @@ type CDNSSLKeyCert struct {
Crt string `json:"crt"`
Key string `json:"key"`
}
+
+type CDNGenerateKSKReq struct {
+ ExpirationDays *uint64 `json:"expirationDays"`
+ EffectiveDate *time.Time `json:"effectiveDate"`
+}
+
+func (r *CDNGenerateKSKReq) Validate(tx *sql.Tx) error {
+ r.Sanitize()
+ errs := []string{}
+ if r.ExpirationDays == nil || *r.ExpirationDays == 0 {
+ errs = append(errs, "expiration missing")
+ }
+ // effective date is optional
+ if len(errs) > 0 {
+ return errors.New("missing fields: " + strings.Join(errs, "; "))
+ }
+ return nil
+}
+
+func (r *CDNGenerateKSKReq) Sanitize() {
+ if r.EffectiveDate == nil {
+ now := time.Now()
+ r.EffectiveDate = &now
+ }
+}
diff --git a/traffic_ops/traffic_ops_golang/cdn/genksk.go b/traffic_ops/traffic_ops_golang/cdn/genksk.go
new file mode 100644
index 0000000..6957d33
--- /dev/null
+++ b/traffic_ops/traffic_ops_golang/cdn/genksk.go
@@ -0,0 +1,200 @@
+package cdn
+
+/*
+ * 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"
+ "net/http"
+ "strconv"
+ "time"
+
+ "github.com/apache/trafficcontrol/lib/go-log"
+ "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/deliveryservice"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/riaksvc"
+)
+
+const DefaultKSKTTLSeconds = 60
+const DefaultKSKEffectiveMultiplier = 2
+
+func GenerateKSK(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()
+
+ cdnName := tc.CDNName(inf.Params["name"])
+ req := tc.CDNGenerateKSKReq{}
+ if err := api.Parse(r.Body, inf.Tx.Tx, &req); err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, errors.New("parsing request: "+err.Error()), nil)
+ return
+ }
+
+ ttl, multiplier, err := getKSKParams(inf.Tx.Tx, cdnName)
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("getting CDN KSK parameters: "+err.Error()))
+ return
+ }
+ if ttl == nil {
+ kskTTL := uint64(DefaultKSKTTLSeconds)
+ ttl = &kskTTL
+ }
+ if multiplier == nil {
+ mult := uint64(DefaultKSKEffectiveMultiplier)
+ multiplier = &mult
+ }
+
+ dnssecKeys, ok, err := riaksvc.GetDNSSECKeys(string(cdnName), inf.Tx.Tx, inf.Config.RiakAuthOptions)
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("getting CDN DNSSEC keys: "+err.Error()))
+ return
+ }
+ if !ok {
+ log.Warnln("Generating CDN '" + string(cdnName) + "' KSK: no keys found in Riak, generating and inserting new key anyway")
+ }
+
+ isKSK := true
+ newKey, err := regenExpiredKeys(isKSK, dnssecKeys[string(cdnName)], *req.EffectiveDate, true, true)
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("regenerating CDN DNSSEC keys: "+err.Error()))
+ return
+ }
+ dnssecKeys[string(cdnName)] = newKey
+
+ if err := riaksvc.PutDNSSECKeys(dnssecKeys, string(cdnName), inf.Tx.Tx, inf.Config.RiakAuthOptions); err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("putting CDN DNSSEC keys: "+err.Error()))
+ return
+ }
+ api.WriteResp(w, r, "Successfully generated ksk dnssec keys for "+string(cdnName))
+}
+
+// getKSKParams returns the CDN's profile's tld.ttls.DNSKEY and DNSKEY.effective.multiplier parameters. If either parameter doesn't exist, nil is returned.
+func getKSKParams(tx *sql.Tx, cdn tc.CDNName) (*uint64, *uint64, error) {
+ qry := `
+WITH cdn_profile_id AS (
+ SELECT
+ p.id
+ FROM
+ profile p
+ JOIN cdn c ON c.id = p.cdn
+ WHERE
+ c.name = $1
+ AND (p.name like 'CCR%' OR p.name like 'TR%')
+ FETCH FIRST 1 ROWS ONLY
+)
+SELECT
+ pa.name,
+ pa.value
+FROM
+ parameter pa
+ JOIN profile_parameter pp ON pp.parameter = pa.id
+ JOIN profile pr ON pr.id = pp.profile
+ JOIN cdn_profile_id pi on pi.id = pr.id
+WHERE
+ (pa.name = 'tld.ttls.DNSKEY' OR pa.name = 'DNSKEY.effective.multiplier')
+`
+ rows, err := tx.Query(qry, cdn)
+ if err != nil {
+ return nil, nil, errors.New("getting cdn ksk parameters: " + err.Error())
+ }
+ defer rows.Close()
+ ttl := (*uint64)(nil)
+ mult := (*uint64)(nil)
+
+ for rows.Next() {
+ name := ""
+ valStr := ""
+ if err := rows.Scan(&name, &valStr); err != nil {
+ return nil, nil, errors.New("scanning cdn ksk parameters: " + err.Error())
+ }
+ val, err := strconv.ParseUint(valStr, 10, 64)
+ if err != nil {
+ log.Warnln("getting CDN KSK parameters: parameter '" + name + "' value '" + valStr + "' is not a number, skipping")
+ continue
+ }
+ if name == "tld.ttls.DNSKEY" {
+ ttl = &val
+ } else {
+ mult = &val
+ }
+ }
+ return ttl, mult, nil
+}
+
+// regenExpiredKeys regenerates expired keys. The key is the map key into the keys object, which may be a CDN name or a delivery service name.
+func regenExpiredKeys(typeKSK bool, existingKeys tc.DNSSECKeySet, effectiveDate time.Time, tld bool, resetExp bool) (tc.DNSSECKeySet, error) {
+
+ existingKey := ([]tc.DNSSECKey)(nil)
+ if typeKSK {
+ existingKey = existingKeys.KSK
+ } else {
+ existingKey = existingKeys.ZSK
+ }
+
+ oldKey := tc.DNSSECKey{}
+ oldKeyFound := false
+ for _, key := range existingKey {
+ if key.Status == tc.DNSSECKeyStatusNew {
+ oldKey = key
+ oldKeyFound = true
+ break
+ }
+ }
+
+ if !oldKeyFound {
+ return existingKeys, errors.New("no old key found") // TODO verify this is correct (Perl doesn't check)
+ }
+
+ name := oldKey.Name
+ ttl := time.Duration(oldKey.TTLSeconds) * time.Second
+ expiration := oldKey.ExpirationDateUnix
+ inception := oldKey.InceptionDateUnix
+ const secPerDay = 86400
+ expirationDays := (expiration - inception) / secPerDay
+
+ newInception := time.Now()
+ newExpiration := time.Now().Add(time.Duration(expirationDays) * time.Hour * 24)
+
+ keyType := tc.DNSSECKSKType
+ if !typeKSK {
+ keyType = tc.DNSSECZSKType
+ }
+ newKey, err := deliveryservice.GetDNSSECKeys(keyType, name, ttl, newInception, newExpiration, tc.DNSSECKeyStatusNew, effectiveDate, tld)
+ if err != nil {
+ return tc.DNSSECKeySet{}, errors.New("getting and generating DNSSEC keys: " + err.Error())
+ }
+
+ oldKey.Status = tc.DNSSECKeyStatusExpired
+ if resetExp {
+ oldKey.ExpirationDateUnix = effectiveDate.Unix()
+ }
+
+ regenKeys := tc.DNSSECKeySet{}
+ if typeKSK {
+ regenKeys = tc.DNSSECKeySet{ZSK: existingKeys.ZSK, KSK: []tc.DNSSECKey{newKey, oldKey}}
+ } else {
+ regenKeys = tc.DNSSECKeySet{ZSK: []tc.DNSSECKey{newKey, oldKey}, KSK: existingKeys.KSK}
+ }
+ return regenKeys, nil
+}
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index f40c06b..f7d4715 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -318,6 +318,8 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
{1.1, http.MethodPut, `cdns/{name}/federations/{id}$`, api.UpdateHandler(cdnfederation.GetTypeSingleton()), auth.PrivLevelAdmin, Authenticated, nil},
{1.1, http.MethodDelete, `cdns/{name}/federations/{id}$`, api.DeleteHandler(cdnfederation.GetTypeSingleton()), auth.PrivLevelAdmin, Authenticated, nil},
+ {1.4, http.MethodPost, `cdns/{name}/dnsseckeys/ksk/generate$`, cdn.GenerateKSK, auth.PrivLevelAdmin, Authenticated, nil},
+
//Origins
{1.3, http.MethodGet, `origins/?(\.json)?$`, api.ReadHandler(origin.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
{1.3, http.MethodGet, `origins/?$`, api.ReadHandler(origin.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
[trafficcontrol] 02/02: Add docs for cdns/dnsseckeys/ksk/generate
Posted by el...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
elsloo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
commit 2025541bf3a132fc069b9691f66fbfaef2b58559
Author: Robert Butts <ro...@apache.org>
AuthorDate: Thu Oct 4 10:32:25 2018 -0600
Add docs for cdns/dnsseckeys/ksk/generate
---
docs/source/api/index.rst | 1 +
docs/source/api/v14/cdn.rst | 66 +++++++++++++++++++++++++++++++++++++
docs/source/api/{ => v14}/index.rst | 26 +++++++--------
3 files changed, 78 insertions(+), 15 deletions(-)
diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst
index 6cdf32e..9f02e95 100644
--- a/docs/source/api/index.rst
+++ b/docs/source/api/index.rst
@@ -25,4 +25,5 @@ A guide to external RESTful APIs for Traffic Ops
v11/index
v12/index
v13/index
+ v14/index
diff --git a/docs/source/api/v14/cdn.rst b/docs/source/api/v14/cdn.rst
new file mode 100644
index 0000000..ce5491e
--- /dev/null
+++ b/docs/source/api/v14/cdn.rst
@@ -0,0 +1,66 @@
+..
+..
+.. 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.
+..
+
+.. _to-api-v14-cdns:
+
+CDN
+==========
+
+.. _to-api-v14-cdns-route:
+
+/api/1.4/cdns
+++++++++++++++++++++
+
+**GET api/1.4/cdns/:name/dnsseckeys/ksk/generate**
+
+ Authentication Required: Yes
+
+ Role(s) Required: None
+
+ **Request Query Parameters**
+
+ +--------------------+----------+----------------------------------------------------------------------------------------------------+
+ | Name | Required | Description |
+ +====================+==========+====================================================================================================+
+ | ``expirationDays`` | yes | The number of days until the new generated ksk expires. |
+ +--------------------+----------+----------------------------------------------------------------------------------------------------+
+ | ``effectiveDate`` | no | The time the new generated ksk becomes effective, in RFC3339 format. Defaults to the current time. |
+ +--------------------+----------+----------------------------------------------------------------------------------------------------+
+
+ **Request Example** ::
+
+ {
+ "expirationDays": 100,
+ "effectiveDate": "2021-01-01T00:00:00.0000000-04:00"
+ }
+
+|
+
+ **Response Properties**
+
+ +-----------------------------------+--------+--------------------------------------------------------------------------+
+ | Parameter | Type | Description |
+ +===================================+========+==========================================================================+
+ | ``response`` | string | response string |
+ +-----------------------------------+--------+--------------------------------------------------------------------------+
+
+ **Response Example** ::
+
+ {
+ "response": Successfully generated ksk dnssec keys for my-cdn-name"
+ }
+
+|
+
diff --git a/docs/source/api/index.rst b/docs/source/api/v14/index.rst
similarity index 77%
copy from docs/source/api/index.rst
copy to docs/source/api/v14/index.rst
index 6cdf32e..a7af22f 100644
--- a/docs/source/api/index.rst
+++ b/docs/source/api/v14/index.rst
@@ -1,28 +1,24 @@
-..
-..
+..
+..
.. 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.
-..
+..
-APIs
-****
-A guide to external RESTful APIs for Traffic Ops
+
+API 1.4 Reference
+*****************
+Traffic Ops API V1.4
.. toctree::
- :maxdepth: 2
+ :maxdepth: 1
- traffic_ops_api
- routes
- v11/index
- v12/index
- v13/index
-
+ cdn