Skip to content
Permalink
Browse files

bulk import services based on CSV

  • Loading branch information...
hunterlong committed May 14, 2019
1 parent adf8cda commit 359c00c250c663f91766cabfb4cc8e334e8da8c4
Showing with 110 additions and 5 deletions.
  1. +4 −3 Makefile
  2. +1 −0 handlers/routes.go
  3. +88 −0 handlers/settings.go
  4. +2 −0 source/tmpl/bulk_upload.csv
  5. +13 −0 source/tmpl/settings.gohtml
  6. +1 −1 source/wiki.go
  7. +1 −1 version.txt
@@ -6,13 +6,14 @@ GOCMD=go
GOBUILD=$(GOCMD) build -a
GOTEST=$(GOCMD) test
GOGET=$(GOCMD) get
GOVERSION=1.12.x
GOINSTALL=$(GOCMD) install
XGO=GOPATH=$(GOPATH) xgo -go 1.12.x --dest=build
XGO=GOPATH=$(GOPATH) xgo -go $(GOVERSION) --dest=build
BUILDVERSION=-ldflags "-X main.VERSION=${VERSION} -X main.COMMIT=$(TRAVIS_COMMIT)"
RICE=$(GOPATH)/bin/rice
PATH:=/usr/local/bin:$(GOPATH)/bin:$(PATH)
PUBLISH_BODY='{ "request": { "branch": "master", "message": "Homebrew update version v${VERSION}", "config": { "env": { "VERSION": "${VERSION}", "COMMIT": "$(TRAVIS_COMMIT)" } } } }'
TRAVIS_BUILD_CMD='{ "request": { "branch": "master", "message": "Compile master for Statping v${VERSION}", "config": { "os": [ "linux" ], "language": "go", "go": [ "1.12.x" ], "go_import_path": "github.com/hunterlong/statping", "install": true, "sudo": "required", "services": [ "docker" ], "env": { "VERSION": "${VERSION}" }, "matrix": { "allow_failures": [ { "go": "master" } ], "fast_finish": true }, "before_deploy": [ "git config --local user.name \"hunterlong\"", "git config --local user.email \"info@socialeck.com\"", "git tag v$(VERSION) --force"], "deploy": [ { "provider": "releases", "api_key": "$(GH_TOKEN)", "file_glob": true, "file": "build/*", "skip_cleanup": true } ], "notifications": { "email": false }, "before_script": ["gem install sass"], "script": [ "wget -O statping.gpg $(SIGN_URL)", "gpg --import statping.gpg", "travis_wait 30 docker pull karalabe/xgo-latest", "make release" ], "after_success": [], "after_deploy": [ "make publish-homebrew" ] } } }'
TRAVIS_BUILD_CMD='{ "request": { "branch": "master", "message": "Compile master for Statping v${VERSION}", "config": { "os": [ "linux" ], "language": "go", "go": [ "${GOVERSION}" ], "go_import_path": "github.com/hunterlong/statping", "install": true, "sudo": "required", "services": [ "docker" ], "env": { "VERSION": "${VERSION}" }, "matrix": { "allow_failures": [ { "go": "master" } ], "fast_finish": true }, "before_deploy": [ "git config --local user.name \"hunterlong\"", "git config --local user.email \"info@socialeck.com\"", "git tag v$(VERSION) --force"], "deploy": [ { "provider": "releases", "api_key": "$(GH_TOKEN)", "file_glob": true, "file": "build/*", "skip_cleanup": true } ], "notifications": { "email": false }, "before_script": ["gem install sass"], "script": [ "wget -O statping.gpg $(SIGN_URL)", "gpg --import statping.gpg", "travis_wait 30 docker pull karalabe/xgo-latest", "make release" ], "after_success": [], "after_deploy": [ "make publish-homebrew" ] } } }'
TEST_DIR=$(GOPATH)/src/github.com/hunterlong/statping
PATH:=$(PATH)

@@ -156,7 +157,7 @@ docker-build-dev:

# build Cypress UI testing :cypress docker tag
docker-build-cypress: clean
GOPATH=$(GOPATH) xgo -out statping -go 1.12.x -ldflags "-X main.VERSION=${VERSION} -X main.COMMIT=$(TRAVIS_COMMIT)" --targets=linux/amd64 ./cmd
GOPATH=$(GOPATH) xgo -out statping -go $(GOVERSION) -ldflags "-X main.VERSION=${VERSION} -X main.COMMIT=$(TRAVIS_COMMIT)" --targets=linux/amd64 ./cmd
docker build -t hunterlong/statping:cypress -f dev/Dockerfile-cypress .
rm -f statping

@@ -85,6 +85,7 @@ func Router() *mux.Router {
r.Handle("/settings/build", authenticated(saveAssetsHandler, true)).Methods("GET")
r.Handle("/settings/delete_assets", authenticated(deleteAssetsHandler, true)).Methods("GET")
r.Handle("/settings/export", authenticated(exportHandler, true)).Methods("GET")
r.Handle("/settings/bulk_import", authenticated(bulkImportHandler, true)).Methods("POST")

// SERVICE Routes
r.Handle("/services", http.HandlerFunc(servicesHandler)).Methods("GET")
@@ -16,14 +16,18 @@
package handlers

import (
"bytes"
"fmt"
"github.com/hunterlong/statping/core"
"github.com/hunterlong/statping/source"
"github.com/hunterlong/statping/types"
"github.com/hunterlong/statping/utils"
"io"
"net/http"
"net/url"
"strconv"
"strings"
"time"
)

func settingsHandler(w http.ResponseWriter, r *http.Request) {
@@ -103,6 +107,90 @@ func deleteAssetsHandler(w http.ResponseWriter, r *http.Request) {
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "/settings")
}

func bulkImportHandler(w http.ResponseWriter, r *http.Request) {
var fileData bytes.Buffer
file, _, err := r.FormFile("file")
if err != nil {
utils.Log(3, fmt.Errorf("error bulk import services: %v", err))
w.Write([]byte(err.Error()))
return
}
defer file.Close()

io.Copy(&fileData, file)
data := fileData.String()

for i, line := range strings.Split(strings.TrimSuffix(data, "\n"), "\n")[1:] {
col := strings.Split(line, ",")

newService, err := commaToService(col)
if err != nil {
utils.Log(3, fmt.Errorf("issue with row %v: %v", i, err))
return
}

service := core.ReturnService(newService)
_, err = service.Create(true)
if err != nil {
utils.Log(3, fmt.Errorf("cannot create service %v: %v", col[0], err))
return
}
utils.Log(1, fmt.Sprintf("Created new service %v", service.Name))
}

ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "/settings")
}

// commaToService will convert a CSV comma delimited string slice to a Service type
// this function is used for the bulk import services feature
func commaToService(s []string) (*types.Service, error) {
if len(s) != 16 {
err := fmt.Errorf("does not have the expected amount of %v columns for a service", 16)
return nil, err
}

interval, err := time.ParseDuration(s[4])
if err != nil {
return nil, err
}

timeout, err := time.ParseDuration(s[9])
if err != nil {
return nil, err
}

allowNotifications, err := strconv.ParseBool(s[10])
if err != nil {
return nil, err
}

public, err := strconv.ParseBool(s[11])
if err != nil {
return nil, err
}

newService := &types.Service{
Name: s[0],
Domain: s[1],
Expected: types.NewNullString(s[2]),
ExpectedStatus: int(utils.ToInt(s[3])),
Interval: int(utils.ToInt(interval.Seconds())),
Type: s[5],
Method: s[6],
PostData: types.NewNullString(s[7]),
Port: int(utils.ToInt(s[8])),
Timeout: int(utils.ToInt(timeout.Seconds())),
AllowNotifications: types.NewNullBool(allowNotifications),
Public: types.NewNullBool(public),
GroupId: int(utils.ToInt(s[12])),
Headers: types.NewNullString(s[13]),
Permalink: types.NewNullString(s[14]),
}

return newService, nil

}

func parseForm(r *http.Request) url.Values {
r.ParseForm()
return r.PostForm
@@ -0,0 +1,2 @@
name,domain,expected,expected_status,interval,type,method,post_data,port,timeout,order,allow_notifications,public,group_id,headers,permalink
Bulk Upload,http://google.com,,200,60s,http,get,,,60s,1,true,true,,Authorization=example,bulk_example
@@ -139,6 +139,19 @@
<a class="btn btn-sm btn-primary" href={{safeURL QrAuth}}>Open in Statping App</a>
{{end}}


<h3 class="mt-3">Bulk Import Services</h3>
You can import multiple services based on a CSV file with the format shown on the <a href="https://github.com/hunterlong/statping/wiki/Bulk-Import-Services" target="_blank">Bulk Import Wiki</a>.

<form action="/settings/bulk_import" method="POST" enctype="multipart/form-data" class="form-inline">
<div class="form-group">
<input type="file" name="file" class="form-control-file" accept=".csv">
</div>
<div class="form-group">
<button type="submit" class="btn btn-success ml-3">Upload</button>
</div>
</form>

</div>

<div class="tab-pane" id="v-pills-style" role="tabpanel" aria-labelledby="v-pills-style-tab">

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -1 +1 @@
0.80.57
0.80.58

0 comments on commit 359c00c

Please sign in to comment.
You can’t perform that action at this time.