mirror of https://github.com/statping/statping
bulk import services based on CSV
parent
adf8cdab20
commit
359c00c250
7
Makefile
7
Makefile
|
@ -6,13 +6,14 @@ GOCMD=go
|
||||||
GOBUILD=$(GOCMD) build -a
|
GOBUILD=$(GOCMD) build -a
|
||||||
GOTEST=$(GOCMD) test
|
GOTEST=$(GOCMD) test
|
||||||
GOGET=$(GOCMD) get
|
GOGET=$(GOCMD) get
|
||||||
|
GOVERSION=1.12.x
|
||||||
GOINSTALL=$(GOCMD) install
|
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)"
|
BUILDVERSION=-ldflags "-X main.VERSION=${VERSION} -X main.COMMIT=$(TRAVIS_COMMIT)"
|
||||||
RICE=$(GOPATH)/bin/rice
|
RICE=$(GOPATH)/bin/rice
|
||||||
PATH:=/usr/local/bin:$(GOPATH)/bin:$(PATH)
|
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)" } } } }'
|
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
|
TEST_DIR=$(GOPATH)/src/github.com/hunterlong/statping
|
||||||
PATH:=$(PATH)
|
PATH:=$(PATH)
|
||||||
|
|
||||||
|
@ -156,7 +157,7 @@ docker-build-dev:
|
||||||
|
|
||||||
# build Cypress UI testing :cypress docker tag
|
# build Cypress UI testing :cypress docker tag
|
||||||
docker-build-cypress: clean
|
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 .
|
docker build -t hunterlong/statping:cypress -f dev/Dockerfile-cypress .
|
||||||
rm -f statping
|
rm -f statping
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ func Router() *mux.Router {
|
||||||
r.Handle("/settings/build", authenticated(saveAssetsHandler, true)).Methods("GET")
|
r.Handle("/settings/build", authenticated(saveAssetsHandler, true)).Methods("GET")
|
||||||
r.Handle("/settings/delete_assets", authenticated(deleteAssetsHandler, 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/export", authenticated(exportHandler, true)).Methods("GET")
|
||||||
|
r.Handle("/settings/bulk_import", authenticated(bulkImportHandler, true)).Methods("POST")
|
||||||
|
|
||||||
// SERVICE Routes
|
// SERVICE Routes
|
||||||
r.Handle("/services", http.HandlerFunc(servicesHandler)).Methods("GET")
|
r.Handle("/services", http.HandlerFunc(servicesHandler)).Methods("GET")
|
||||||
|
|
|
@ -16,14 +16,18 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hunterlong/statping/core"
|
"github.com/hunterlong/statping/core"
|
||||||
"github.com/hunterlong/statping/source"
|
"github.com/hunterlong/statping/source"
|
||||||
"github.com/hunterlong/statping/types"
|
"github.com/hunterlong/statping/types"
|
||||||
"github.com/hunterlong/statping/utils"
|
"github.com/hunterlong/statping/utils"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func settingsHandler(w http.ResponseWriter, r *http.Request) {
|
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")
|
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 {
|
func parseForm(r *http.Request) url.Values {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
return r.PostForm
|
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>
|
<a class="btn btn-sm btn-primary" href={{safeURL QrAuth}}>Open in Statping App</a>
|
||||||
{{end}}
|
{{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>
|
||||||
|
|
||||||
<div class="tab-pane" id="v-pills-style" role="tabpanel" aria-labelledby="v-pills-style-tab">
|
<div class="tab-pane" id="v-pills-style" role="tabpanel" aria-labelledby="v-pills-style-tab">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by go generate; DO NOT EDIT.
|
// Code generated by go generate; DO NOT EDIT.
|
||||||
// This file was generated by robots at
|
// 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.
|
// This contains the most recently Markdown source for the Statping Wiki.
|
||||||
package source
|
package source
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.80.57
|
0.80.58
|
||||||
|
|
Loading…
Reference in New Issue