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)

Reply via email to