Add traffic_ops_golang to RPM, service
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/4fd7feb6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/4fd7feb6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/4fd7feb6 Branch: refs/heads/master Commit: 4fd7feb624a6c888c8fc3b49a1104212b7dc9c2f Parents: 04ed9f1 Author: Robert Butts <robert.o.bu...@gmail.com> Authored: Sun Jul 9 09:23:49 2017 -0600 Committer: Dewayne Richardson <dewr...@apache.org> Committed: Thu Aug 10 09:46:02 2017 -0600 ---------------------------------------------------------------------- traffic_ops/build/traffic_ops.spec | 36 ++++++++++++++++++++ traffic_ops/etc/init.d/traffic_ops | 2 ++ traffic_ops/traffic_ops_golang/auth.go | 25 ++++++++++++++ traffic_ops/traffic_ops_golang/monitoring.go | 2 ++ traffic_ops/traffic_ops_golang/routes.go | 28 +++++++++------ .../traffic_ops_golang.config | 2 +- .../traffic_ops_golang/traffic_ops_golang.go | 6 +++- traffic_ops/traffic_ops_golang/wrappers.go | 9 ++++- 8 files changed, 97 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4fd7feb6/traffic_ops/build/traffic_ops.spec ---------------------------------------------------------------------- diff --git a/traffic_ops/build/traffic_ops.spec b/traffic_ops/build/traffic_ops.spec index cda9f59..3c899fe 100644 --- a/traffic_ops/build/traffic_ops.spec +++ b/traffic_ops/build/traffic_ops.spec @@ -55,6 +55,31 @@ Built: %(date) by %{getenv: USER} # update version referenced in the source perl -pi.bak -e 's/__VERSION__/%{version}-%{release}/' app/lib/UI/Utils.pm + export GOPATH=$(pwd) + # Create build area with proper gopath structure + mkdir -p src pkg bin || { echo "Could not create directories in $(pwd): $!"; exit 1; } + + # build tocookie (dependencies within traffic_control will fail to `go get` unless prebuilt) + godir=src/github.com/apache/incubator-trafficcontrol/traffic_ops/experimental/tocookie + ( mkdir -p "$godir" && \ + cd "$godir" && \ + cp -r "$TC_DIR"/traffic_ops/experimental/tocookie/* . && \ + echo "go getting tocookie at $(pwd)" && \ + go get -v \ + ) || { echo "Could not build go tocookie at $(pwd): $!"; exit 1; } + + # build traffic_ops_golang binary + godir=src/github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang + oldpwd=$(pwd) + ( mkdir -p "$godir" && \ + cd "$godir" && \ + cp -r "$TC_DIR"/traffic_ops/traffic_ops_golang/* . && \ + echo "go getting at $(pwd)" && \ + go get -d -v && \ + echo "go building at $(pwd)" && \ + go build -ldflags "-B 0x`git rev-parse HEAD`" \ + ) || { echo "Could not build go program at $(pwd): $!"; exit 1; } + %install if [ -d $RPM_BUILD_ROOT ]; then @@ -66,6 +91,9 @@ Built: %(date) by %{getenv: USER} fi %__cp -R $RPM_BUILD_DIR/traffic_ops-%{version}/* $RPM_BUILD_ROOT/%{PACKAGEDIR} + echo "go rming $RPM_BUILD_ROOT/%{PACKAGEDIR}/{pkg,src,bin}" + %__rm -rf $RPM_BUILD_ROOT/%{PACKAGEDIR}/{pkg,src,bin} + %__mkdir -p $RPM_BUILD_ROOT/var/www/files %__cp install/data/perl/osversions.cfg $RPM_BUILD_ROOT/var/www/files/. @@ -73,6 +101,14 @@ Built: %(date) by %{getenv: USER} %__mkdir -p $RPM_BUILD_ROOT/%{PACKAGEDIR}/app/public/routing fi + # install traffic_ops_golang binary + if [ ! -d $RPM_BUILD_ROOT/%{PACKAGEDIR}/app/bin ]; then + %__mkdir -p $RPM_BUILD_ROOT/%{PACKAGEDIR}/app/bin + fi + + src=src/github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang + %__cp -p "$src"/traffic_ops_golang "${RPM_BUILD_ROOT}"/opt/traffic_ops/app/bin/traffic_ops_golang + %__cp -p "$src"/traffic_ops_golang.config "${RPM_BUILD_ROOT}"/opt/traffic_ops/app/conf/traffic_ops_golang.config %pre /usr/bin/getent group %{TRAFFIC_OPS_GROUP} || /usr/sbin/groupadd -r %{TRAFFIC_OPS_GROUP} /usr/bin/getent passwd %{TRAFFIC_OPS_USER} || /usr/sbin/useradd -r -d %{PACKAGEDIR} -s /sbin/nologin %{TRAFFIC_OPS_USER} -g %{TRAFFIC_OPS_GROUP} http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4fd7feb6/traffic_ops/etc/init.d/traffic_ops ---------------------------------------------------------------------- diff --git a/traffic_ops/etc/init.d/traffic_ops b/traffic_ops/etc/init.d/traffic_ops index d3090d5..01eef6f 100755 --- a/traffic_ops/etc/init.d/traffic_ops +++ b/traffic_ops/etc/init.d/traffic_ops @@ -59,11 +59,13 @@ stopHypnotoad () start () { echo -e "Starting Traffic Ops\n" + cd $TO_DIR && $TO_DIR/bin/traffic_ops_golang -cfg $TO_DIR/conf/traffic_ops_golang.config & cd $TO_DIR && $TO_DIR/local/bin/hypnotoad script/cdn } stop () { + killproc $TO_DIR/bin/traffic_ops_golang stopHypnotoad } http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4fd7feb6/traffic_ops/traffic_ops_golang/auth.go ---------------------------------------------------------------------- diff --git a/traffic_ops/traffic_ops_golang/auth.go b/traffic_ops/traffic_ops_golang/auth.go new file mode 100644 index 0000000..75849c1 --- /dev/null +++ b/traffic_ops/traffic_ops_golang/auth.go @@ -0,0 +1,25 @@ +package main + +import ( + "database/sql" + "log" // TODO change to traffic_monitor_golang/common/log +) + +func preparePrivLevelStmt(db *sql.DB) (*sql.Stmt, error) { + return db.Prepare("select r.priv_level from tm_user as u join role as r on u.role = r.id where u.username = $1") +} + +func hasPrivLevel(privLevelStmt *sql.Stmt, user string, level int) bool { + var privLevel int + err := privLevelStmt.QueryRow(user).Scan(&privLevel) + switch { + case err == sql.ErrNoRows: + log.Println("Error checking user " + user + " priv level: user not in database") + return false + case err != nil: + log.Println("Error checking user " + user + " priv level: " + err.Error()) + return false + default: + return privLevel >= level + } +} http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4fd7feb6/traffic_ops/traffic_ops_golang/monitoring.go ---------------------------------------------------------------------- diff --git a/traffic_ops/traffic_ops_golang/monitoring.go b/traffic_ops/traffic_ops_golang/monitoring.go index b353fb5..c669d0b 100644 --- a/traffic_ops/traffic_ops_golang/monitoring.go +++ b/traffic_ops/traffic_ops_golang/monitoring.go @@ -10,6 +10,8 @@ import ( "time" ) +const MonitoringPrivLevel = 10 + const CacheMonitorConfigFile = "rascal.properties" const MonitorType = "RASCAL" const RouterType = "CCR" http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4fd7feb6/traffic_ops/traffic_ops_golang/routes.go ---------------------------------------------------------------------- diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go index cc14450..f347eef 100644 --- a/traffic_ops/traffic_ops_golang/routes.go +++ b/traffic_ops/traffic_ops_golang/routes.go @@ -3,6 +3,7 @@ package main import ( "crypto/tls" "database/sql" + "fmt" "net/http" "net/http/httputil" "regexp" @@ -18,10 +19,6 @@ type ParamMap map[string]string type RegexHandlerFunc func(w http.ResponseWriter, r *http.Request, params ParamMap) -func getMonitoringRoute(d ServerData) RegexHandlerFunc { - return wrapLogTime(wrapAuth(monitoringHandler(d.DB), d.NoAuth, d.TOSecret)) -} - // getRootHandler returns the / handler for the service, which reverse-proxies the old Perl Traffic Ops func getRootHandler(d ServerData) http.Handler { // debug @@ -33,11 +30,16 @@ func getRootHandler(d ServerData) http.Handler { return rp } -// GetRoutes returns the map of regex routes, and a catchall route if no regex matches. -func GetRoutes(d ServerData) (map[string]RegexHandlerFunc, http.Handler) { +// GetRoutes returns the map of regex routes, and a catchall route for when no regex matches. +func GetRoutes(d ServerData) (map[string]RegexHandlerFunc, http.Handler, error) { + privLevelStmt, err := preparePrivLevelStmt(d.DB) + if err != nil { + return nil, nil, fmt.Errorf("Error preparing db priv level query: ", err) + } + return map[string]RegexHandlerFunc{ - "api/1.2/cdns/{cdn}/configs/monitoring.json": getMonitoringRoute(d), - }, getRootHandler(d) + "api/1.2/cdns/{cdn}/configs/monitoring.json": wrapLogTime(wrapAuth(monitoringHandler(d.DB), d.NoAuth, d.TOSecret, privLevelStmt, MonitoringPrivLevel)), + }, getRootHandler(d), nil } type CompiledRoute struct { @@ -86,10 +88,16 @@ func Handler(routes map[string]CompiledRoute, catchall http.Handler, w http.Resp catchall.ServeHTTP(w, r) } -func RegisterRoutes(d ServerData) { - routes, catchall := GetRoutes(d) +func RegisterRoutes(d ServerData) error { + routes, catchall, err := GetRoutes(d) + if err != nil { + return err + } + compiledRoutes := CompileRoutes(&routes) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { Handler(compiledRoutes, catchall, w, r) }) + + return nil } http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4fd7feb6/traffic_ops/traffic_ops_golang/traffic_ops_golang.config ---------------------------------------------------------------------- diff --git a/traffic_ops/traffic_ops_golang/traffic_ops_golang.config b/traffic_ops/traffic_ops_golang/traffic_ops_golang.config index 19d2599..6bd9703 100644 --- a/traffic_ops/traffic_ops_golang/traffic_ops_golang.config +++ b/traffic_ops/traffic_ops_golang/traffic_ops_golang.config @@ -1,5 +1,5 @@ { - "port": "443", + "port": "", "db_user": "bill", "db_pass": "thelizard", "db_server": "db.trafficops.example.net", http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4fd7feb6/traffic_ops/traffic_ops_golang/traffic_ops_golang.go ---------------------------------------------------------------------- diff --git a/traffic_ops/traffic_ops_golang/traffic_ops_golang.go b/traffic_ops/traffic_ops_golang/traffic_ops_golang.go index 48d3c4e..aec0637 100644 --- a/traffic_ops/traffic_ops_golang/traffic_ops_golang.go +++ b/traffic_ops/traffic_ops_golang/traffic_ops_golang.go @@ -47,7 +47,11 @@ func main() { } defer db.Close() - RegisterRoutes(ServerData{DB: db, Config: cfg}) + if err := RegisterRoutes(ServerData{DB: db, Config: cfg}); err != nil { + fmt.Printf("Error registering routes: %v\n", err) + return + } + fmt.Println("Listening on " + cfg.HTTPPort) if err := http.ListenAndServeTLS(":"+cfg.HTTPPort, cfg.CertPath, cfg.KeyPath, nil); err != nil { fmt.Printf("Error stopping server: %v\n", err) http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4fd7feb6/traffic_ops/traffic_ops_golang/wrappers.go ---------------------------------------------------------------------- diff --git a/traffic_ops/traffic_ops_golang/wrappers.go b/traffic_ops/traffic_ops_golang/wrappers.go index daf5e34..c5fd9c0 100644 --- a/traffic_ops/traffic_ops_golang/wrappers.go +++ b/traffic_ops/traffic_ops_golang/wrappers.go @@ -1,6 +1,7 @@ package main import ( + "database/sql" "fmt" "github.com/apache/incubator-trafficcontrol/traffic_ops/experimental/tocookie" "log" // TODO change to traffic_monitor_golang/common/log @@ -8,7 +9,7 @@ import ( "time" ) -func wrapAuth(h RegexHandlerFunc, noAuth bool, secret string) RegexHandlerFunc { +func wrapAuth(h RegexHandlerFunc, noAuth bool, secret string, privLevelStmt *sql.Stmt, privLevelRequired int) RegexHandlerFunc { if noAuth { return h } @@ -37,6 +38,12 @@ func wrapAuth(h RegexHandlerFunc, noAuth bool, secret string) RegexHandlerFunc { return } + username := oldCookie.AuthData + if !hasPrivLevel(privLevelStmt, username, privLevelRequired) { + handleUnauthorized("insufficient privileges") + return + } + newCookieVal := tocookie.Refresh(oldCookie, secret) http.SetCookie(w, &http.Cookie{Name: tocookie.Name, Value: newCookieVal}) h(w, r, p)