Mercurial > gemma
changeset 386:999f4f83a072
Configure GeoServer via REST-API. TODO: Configure layers.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 13 Aug 2018 13:41:08 +0200 |
parents | 3cfab707f909 |
children | 0f78b13f4a9a |
files | cmd/gemma/geoserver.go cmd/gemma/main.go config/config.go misc/encode.go |
diffstat | 4 files changed, 207 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmd/gemma/geoserver.go Mon Aug 13 13:41:08 2018 +0200 @@ -0,0 +1,188 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "log" + "net/http" + + "gemma.intevation.de/gemma/config" + "gemma.intevation.de/gemma/misc" +) + +const ( + workspaceName = "gemma" + datastoreName = "gemma" + databaseScheme = "waterway" + databaseType = "postgis" +) + +const startupSQL = `SET SESSION AUTHORIZATION waterway_user;` + +func basicAuth(user, password string) func(req *http.Request) { + auth := "Basic " + misc.BasicAuth(user, password) + return func(req *http.Request) { + req.Header.Add("Authorization", auth) + } +} + +func asJSON(req *http.Request) { + req.Header.Set("Content-Type", "application/json") +} + +func ensureWorkspace() error { + var ( + url = config.GeoServerURL() + user = config.GeoServerUser() + password = config.GeoServerPassword() + auth = basicAuth(user, password) + ) + + // Probe workspace. + req, err := http.NewRequest( + http.MethodGet, + url+"/rest/workspaces/"+workspaceName+".json", + nil) + if err != nil { + return err + } + auth(req) + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusNotFound { + log.Println("info: workspace " + workspaceName + " already exists.") + return nil + } + + // Create workspace + const createJSON = `{"workspace":{"name":"` + workspaceName + `"}}` + + req, err = http.NewRequest( + http.MethodPost, + url+"/rest/workspaces", + bytes.NewReader([]byte(createJSON))) + if err != nil { + return err + } + auth(req) + asJSON(req) + if resp, err = http.DefaultClient.Do(req); err != nil { + return err + } + + if resp.StatusCode != http.StatusCreated { + err = fmt.Errorf("Status code '%s' (%d)", + http.StatusText(resp.StatusCode), + resp.StatusCode) + } + + return err +} + +func ensureDataStore() error { + var ( + url = config.GeoServerURL() + user = config.GeoServerUser() + password = config.GeoServerPassword() + auth = basicAuth(user, password) + ) + + // Probe workspace. + req, err := http.NewRequest( + http.MethodGet, + url+"/rest/workspaces/"+workspaceName+"/datastores/"+datastoreName+".json", + nil) + if err != nil { + return err + } + auth(req) + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusNotFound { + log.Println("info: datastore " + datastoreName + " already exists.") + return nil + } + + type entry struct { + Key interface{} `json:"@key"` + Value interface{} `json:"$"` + } + + // Create datastore. + ds := map[string]interface{}{ + "dataStore": map[string]interface{}{ + "name": datastoreName, + "connectionParameters": map[string]interface{}{ + "entry": []entry{ + {"host", config.DBHost()}, + {"port", config.DBPort()}, + {"schema", databaseScheme}, + {"user", config.SysAdmin()}, + {"passwd", config.SysAdminPassword()}, + {"dbtype", databaseType}, + {"Session startup SQL", startupSQL}, + }, + }, + }, + } + var out bytes.Buffer + enc := json.NewEncoder(&out) + if err := enc.Encode(&ds); err != nil { + return err + } + + req, err = http.NewRequest( + http.MethodPost, + url+"/rest/workspaces/"+workspaceName+"/datastores", + bytes.NewReader(out.Bytes())) + if err != nil { + return err + } + auth(req) + asJSON(req) + resp, err = http.DefaultClient.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusCreated { + err = fmt.Errorf("Status code '%s' (%d)", + http.StatusText(resp.StatusCode), + resp.StatusCode) + } + + return err +} + +func prepareGeoServer() error { + + var ( + url = config.GeoServerURL() + //tables = config.GeoServerTables() + ) + + //if url == "" || len(tables) == 0 { + if url == "" { + log.Println("info: No tables to publish on GeoServer") + return nil + } + + if err := ensureWorkspace(); err != nil { + return err + } + + if err := ensureDataStore(); err != nil { + return err + } + + // TODO: Create layers. + + return nil +}
--- a/cmd/gemma/main.go Mon Aug 13 11:17:56 2018 +0200 +++ b/cmd/gemma/main.go Mon Aug 13 13:41:08 2018 +0200 @@ -37,6 +37,13 @@ prepareConnectionPool() + // Do GeoServer setup in background. + go func() { + if err := prepareGeoServer(); err != nil { + log.Printf("warn: preparing GeoServer: %v\n", err) + } + }() + m := mux.NewRouter() controllers.BindRoutes(m)
--- a/config/config.go Mon Aug 13 11:17:56 2018 +0200 +++ b/config/config.go Mon Aug 13 13:41:08 2018 +0200 @@ -25,6 +25,9 @@ func ServiceUser() string { return viper.GetString("service-user") } func ServicePassword() string { return viper.GetString("service-password") } +func SysAdmin() string { return viper.GetString("sys-admin") } +func SysAdminPassword() string { return viper.GetString("sys-admin-password") } + func MailHost() string { return viper.GetString("mail-host") } func MailPort() uint { return uint(viper.GetInt32("mail-port")) } func MailUser() string { return viper.GetString("mail-user") } @@ -96,6 +99,9 @@ str("service-user", "postgres", "user to do service tasks") str("service-password", "", "password of user to do service tasks") + str("sys-admin", "postgres", "user to do admin tasks") + str("sys-admin-password", "", "password of user to do admin tasks") + str("mail-host", "localhost", "server to send mail with") ui("mail-port", 465, "port of server to send mail with") str("mail-user", "gemma", "user to send mail with")
--- a/misc/encode.go Mon Aug 13 11:17:56 2018 +0200 +++ b/misc/encode.go Mon Aug 13 13:41:08 2018 +0200 @@ -1,6 +1,7 @@ package misc import ( + "encoding/base64" "encoding/binary" "io" ) @@ -68,3 +69,8 @@ w.Err = binary.Write(w.Writer, binary.BigEndian, []byte(s)) } } + +func BasicAuth(user, password string) string { + auth := user + ":" + password + return base64.StdEncoding.EncodeToString([]byte(auth)) +}