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 17:16:12 UTC

[trafficcontrol] branch master updated: Add TO Go cdns/name/sslkeys

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


The following commit(s) were added to refs/heads/master by this push:
     new 31b9b97  Add TO Go cdns/name/sslkeys
31b9b97 is described below

commit 31b9b971b5aa04d28c32c39f1fff5c3aad47d93b
Author: Robert Butts <ro...@apache.org>
AuthorDate: Tue Jun 12 13:28:21 2018 -0600

    Add TO Go cdns/name/sslkeys
---
 lib/go-tc/deliveryservice_ssl_keys.go              | 13 +++++
 traffic_ops/traffic_ops_golang/cdn/sslkeys.go      | 56 ++++++++++++++++++++++
 traffic_ops/traffic_ops_golang/riaksvc/dsutil.go   | 47 ++++++++++++++++++
 .../traffic_ops_golang/riaksvc/riak_services.go    | 27 +++++++++--
 traffic_ops/traffic_ops_golang/routes.go           |  1 +
 5 files changed, 141 insertions(+), 3 deletions(-)

diff --git a/lib/go-tc/deliveryservice_ssl_keys.go b/lib/go-tc/deliveryservice_ssl_keys.go
index 1a1a9f1..e366bbc 100644
--- a/lib/go-tc/deliveryservice_ssl_keys.go
+++ b/lib/go-tc/deliveryservice_ssl_keys.go
@@ -187,3 +187,16 @@ func (r CDNDNSSECGenerateReq) Validate(tx *sql.Tx) error {
 }
 
 type URLSigKeys map[string]string
+
+type CDNSSLKeysResp []CDNSSLKey
+
+type CDNSSLKey struct {
+	DeliveryService string        `json:"deliveryservice"`
+	HostName        string        `json:"hostname"`
+	Certificate     CDNSSLKeyCert `json:"certificate"`
+}
+
+type CDNSSLKeyCert struct {
+	Crt string `json:"crt"`
+	Key string `json:"key"`
+}
diff --git a/traffic_ops/traffic_ops_golang/cdn/sslkeys.go b/traffic_ops/traffic_ops_golang/cdn/sslkeys.go
new file mode 100644
index 0000000..b8147c6
--- /dev/null
+++ b/traffic_ops/traffic_ops_golang/cdn/sslkeys.go
@@ -0,0 +1,56 @@
+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"
+
+	"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/basho/riak-go-client"
+)
+
+func GetSSLKeys(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()
+	keys, err := getSSLKeys(inf.Tx.Tx, inf.Config.RiakAuthOptions, inf.Params["name"])
+	if err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("getting cdn ssl keys: "+err.Error()))
+		return
+	}
+	*inf.CommitTx = true
+	api.WriteResp(w, r, keys)
+}
+
+func getSSLKeys(tx *sql.Tx, authOpts *riak.AuthOptions, cdnName string) ([]tc.CDNSSLKey, error) {
+	keys, err := riaksvc.GetCDNSSLKeysObj(tx, authOpts, cdnName)
+	if err != nil {
+		return nil, errors.New("getting cdn ssl keys from Riak: " + err.Error())
+	}
+	return keys, nil
+}
diff --git a/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go b/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
index 7c543a4..c6f36ce 100644
--- a/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
+++ b/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
@@ -309,3 +309,50 @@ func PutURLSigKeys(tx *sql.Tx, authOpts *riak.AuthOptions, ds tc.DeliveryService
 	})
 	return err
 }
+
+const SSLKeysIndex = "sslkeys"
+const CDNSSLKeysLimit = 1000 // TODO: emulates Perl; reevaluate?
+
+func GetCDNSSLKeysObj(tx *sql.Tx, authOpts *riak.AuthOptions, cdnName string) ([]tc.CDNSSLKey, error) {
+	keys := []tc.CDNSSLKey{}
+	err := WithClusterTx(tx, authOpts, func(cluster StorageCluster) error {
+		// get the deliveryservice ssl keys by xmlID and version
+		query := `cdn:` + cdnName
+		filterQuery := `_yz_rk:*latest`
+		searchDocs, err := Search(cluster, SSLKeysIndex, query, filterQuery, CDNSSLKeysLimit)
+		if err != nil {
+			return errors.New("riak search error: " + err.Error())
+		}
+		if len(searchDocs) == 0 {
+			return nil // no error, and leave keys empty
+		}
+		keys = SearchDocsToCDNSSLKeys(searchDocs)
+		return nil
+	})
+	if err != nil {
+		return nil, errors.New("with cluster error: " + err.Error())
+	}
+	return keys, nil
+}
+
+// SearchDocsToCDNSSLKeys converts the SearchDoc array returned by Riak into a CDNSSLKey slice. If a SearchDoc doesn't contain expected fields, it creates the key with those fields defaulted to empty strings.
+func SearchDocsToCDNSSLKeys(docs []*riak.SearchDoc) []tc.CDNSSLKey {
+	keys := []tc.CDNSSLKey{}
+	for _, doc := range docs {
+		key := tc.CDNSSLKey{}
+		if dss := doc.Fields["deliveryservice"]; len(dss) > 0 {
+			key.DeliveryService = dss[0]
+		}
+		if hosts := doc.Fields["hostname"]; len(hosts) > 0 {
+			key.HostName = hosts[0]
+		}
+		if crts := doc.Fields["certificate.crt"]; len(crts) > 0 {
+			key.Certificate.Crt = crts[0]
+		}
+		if keys := doc.Fields["certificate.key"]; len(keys) > 0 {
+			key.Certificate.Key = keys[0]
+		}
+		keys = append(keys, key)
+	}
+	return keys
+}
diff --git a/traffic_ops/traffic_ops_golang/riaksvc/riak_services.go b/traffic_ops/traffic_ops_golang/riaksvc/riak_services.go
index 08a3248..fed4479 100644
--- a/traffic_ops/traffic_ops_golang/riaksvc/riak_services.go
+++ b/traffic_ops/traffic_ops_golang/riaksvc/riak_services.go
@@ -305,7 +305,6 @@ func GetRiakCluster(db *sql.DB, authOptions *riak.AuthOptions) (StorageCluster,
 }
 
 func WithCluster(db *sql.DB, authOpts *riak.AuthOptions, f func(StorageCluster) error) error {
-	log.Errorf("DEBUG WithCluster authOps: %++v\n", authOpts)
 	cluster, err := GetRiakCluster(db, authOpts)
 	if err != nil {
 		return errors.New("getting riak cluster: " + err.Error())
@@ -322,7 +321,6 @@ func WithCluster(db *sql.DB, authOpts *riak.AuthOptions, f func(StorageCluster)
 }
 
 func WithClusterX(db *sqlx.DB, authOpts *riak.AuthOptions, f func(StorageCluster) error) error {
-	log.Errorf("DEBUG WithCluster authOps: %++v\n", authOpts)
 	cluster, err := GetRiakCluster(db.DB, authOpts)
 	if err != nil {
 		return errors.New("getting riak cluster: " + err.Error())
@@ -351,7 +349,6 @@ func GetRiakClusterTx(tx *sql.Tx, authOptions *riak.AuthOptions) (StorageCluster
 }
 
 func WithClusterTx(tx *sql.Tx, authOpts *riak.AuthOptions, f func(StorageCluster) error) error {
-	log.Errorf("DEBUG WithCluster authOps: %++v\n", authOpts)
 	cluster, err := GetRiakClusterTx(tx, authOpts)
 	if err != nil {
 		return errors.New("getting riak cluster: " + err.Error())
@@ -385,3 +382,27 @@ func StopCluster(c StorageCluster) {
 		log.Errorln("stopping riak cluster: " + err.Error())
 	}
 }
+
+// Search searches Riak for the given query. Returns nil and a nil error if no object was found.
+func Search(cluster StorageCluster, index string, query string, filterQuery string, numRows int) ([]*riak.SearchDoc, error) {
+	iCmd, err := riak.NewSearchCommandBuilder().
+		WithIndexName(index).
+		WithQuery(query).
+		WithFilterQuery(filterQuery).
+		WithNumRows(uint32(numRows)).
+		Build()
+	if err != nil {
+		return nil, errors.New("building Riak command: " + err.Error())
+	}
+	if err = cluster.Execute(iCmd); err != nil {
+		return nil, errors.New("executing Riak command index '" + index + "' query '" + query + "': " + err.Error())
+	}
+	cmd, ok := iCmd.(*riak.SearchCommand)
+	if !ok {
+		return nil, fmt.Errorf("Riak command unexpected type %T", iCmd)
+	}
+	if cmd.Response == nil || cmd.Response.NumFound == 0 {
+		return nil, nil
+	}
+	return cmd.Response.Docs, nil
+}
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index 7f869bd..ffffdaa 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -108,6 +108,7 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.1, http.MethodPost, `cachegroups/{id}/queue_update$`, cachegroup.QueueUpdates(d.DB.DB), auth.PrivLevelOperations, Authenticated, nil},
 
 		//CDN
+		{1.1, http.MethodGet, `cdns/name/{name}/sslkeys/?(\.json)?$`, cdn.GetSSLKeys, auth.PrivLevelAdmin, Authenticated, nil},
 		{1.1, http.MethodGet, `cdns/metric_types`, notImplementedHandler, 0, NoAuth, nil}, // MUST NOT end in $, because the 1.x route is longer
 		{1.1, http.MethodGet, `cdns/capacity$`, handlerToFunc(proxyHandler), 0, NoAuth, []Middleware{}},
 		{1.1, http.MethodGet, `cdns/configs/?(\.json)?$`, cdn.GetConfigs(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},