Retrieve function logs from controller (#207)

Establish a proxy server from the controller to the log database.

Redirect query commands send from client to database then proxy back the db response.

Use parameter binding instead of fmt.Sprintf to prevent SQL injection.
This commit is contained in:
Ta-Ching Chen
2017-05-30 14:19:22 -07:00
committed by Soam Vasani
parent 531f69a037
commit 990d943f21
7 changed files with 158 additions and 103 deletions
+36 -7
View File
@@ -21,21 +21,31 @@ import (
"net/http"
"os"
"runtime/debug"
"strings"
log "github.com/Sirupsen/logrus"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/fission/fission"
"github.com/fission/fission/fission/logdb"
)
type API struct {
FunctionStore
HTTPTriggerStore
TimeTriggerStore
EnvironmentStore
WatchStore
}
type (
API struct {
FunctionStore
HTTPTriggerStore
TimeTriggerStore
EnvironmentStore
WatchStore
}
logDBConfig struct {
httpURL string
username string
password string
}
)
func MakeAPI(rs *ResourceStore) *API {
api := &API{
@@ -64,6 +74,23 @@ func (api *API) respondWithError(w http.ResponseWriter, err error) {
http.Error(w, msg, code)
}
func (api *API) getLogDBConfig(dbType string) logDBConfig {
dbType = strings.ToUpper(dbType)
// retrieve db auth config from the env
url := os.Getenv(fmt.Sprintf("%s_URL", dbType))
if url == "" {
// set up default database url
url = logdb.INFLUXDB_URL
}
username := os.Getenv(fmt.Sprintf("%s_USERNAME", dbType))
password := os.Getenv(fmt.Sprintf("%s_PASSWORD", dbType))
return logDBConfig{
httpURL: url,
username: username,
password: password,
}
}
func (api *API) HomeHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
fmt.Fprintf(w, "{\"message\": \"Fission API\", \"version\": \"0.1.0\"}\n")
@@ -103,6 +130,8 @@ func (api *API) Serve(port int) {
r.HandleFunc("/v1/triggers/time/{timeTrigger}", api.TimeTriggerApiUpdate).Methods("PUT")
r.HandleFunc("/v1/triggers/time/{timeTrigger}", api.TimeTriggerApiDelete).Methods("DELETE")
r.HandleFunc("/proxy/{dbType}", api.FunctionLogsApiPost).Methods("POST")
address := fmt.Sprintf(":%v", port)
log.WithFields(log.Fields{"port": port}).Info("Server started")
+34 -2
View File
@@ -17,14 +17,16 @@ limitations under the License.
package controller
import (
"encoding/base64"
"encoding/json"
"io/ioutil"
"net/http"
"net/http/httputil"
"net/url"
"encoding/json"
log "github.com/Sirupsen/logrus"
"github.com/gorilla/mux"
"encoding/base64"
"github.com/fission/fission"
)
@@ -171,3 +173,33 @@ func (api *API) FunctionApiDelete(w http.ResponseWriter, r *http.Request) {
api.respondWithSuccess(w, []byte(""))
}
// FunctionLogsApiPost establishes a proxy server to log database, and redirect
// query command send from client to database then proxy back the db response.
func (api *API) FunctionLogsApiPost(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
// get dbType from url
dbType := vars["dbType"]
// find correspond db http url
dbCnf := api.getLogDBConfig(dbType)
svcUrl, err := url.Parse(dbCnf.httpURL)
if err != nil {
log.Printf("Failed to establish proxy server for function logs: %v", err)
}
// set up proxy server director
director := func(req *http.Request) {
// only replace url Scheme and Host to remote influxDB
// and leave query string intact
req.URL.Scheme = svcUrl.Scheme
req.URL.Host = svcUrl.Host
req.URL.Path = svcUrl.Path
// set up http basic auth for database authentication
req.SetBasicAuth(dbCnf.username, dbCnf.password)
}
proxy := &httputil.ReverseProxy{
Director: director,
}
proxy.ServeHTTP(w, r)
}