bulk import services based on CSV

pull/194/head
Hunter Long 2019-05-14 12:13:52 -07:00
parent adf8cdab20
commit 359c00c250
7 changed files with 110 additions and 5 deletions

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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
1 name domain expected expected_status interval type method post_data port timeout order allow_notifications public group_id headers permalink
2 Bulk Upload http://google.com 200 60s http get 60s 1 true true Authorization=example bulk_example

View File

@ -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">

View File

@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2019-05-02 15:16:38.134302 -0700 PDT m=+0.921403151
// 2019-05-14 12:12:36.365798 -0700 PDT m=+0.459353534
//
// This contains the most recently Markdown source for the Statping Wiki.
package source

View File

@ -1 +1 @@
0.80.57
0.80.58