begin move to go-restful
This commit is contained in:
parent
92d3142d96
commit
f4f285d0dc
@ -13,7 +13,6 @@ import (
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"novit.nc/direktil/pkg/localconfig"
|
||||
)
|
||||
@ -273,7 +272,7 @@ func uploadConfig(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
err = func() (err error) {
|
||||
backupPath := filepath.Join(archivesPath, "config."+time.Now().Format(time.RFC3339)+".yaml.gz")
|
||||
backupPath := filepath.Join(archivesPath, "config."+ulid()+".yaml.gz")
|
||||
|
||||
bck, err := os.Create(backupPath)
|
||||
if err != nil {
|
||||
|
@ -6,7 +6,10 @@ import (
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
restful "github.com/emicklei/go-restful"
|
||||
"novit.nc/direktil/pkg/cas"
|
||||
|
||||
"novit.nc/direktil/local-server/pkg/apiutils"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -30,16 +33,19 @@ func main() {
|
||||
}
|
||||
|
||||
casStore = cas.NewDir(filepath.Join(*dataDir, "cache"))
|
||||
|
||||
go casCleaner()
|
||||
|
||||
apiutils.Setup(func() {
|
||||
restful.Add(buildWS())
|
||||
})
|
||||
|
||||
// by default, serve a host resource by its IP
|
||||
http.HandleFunc("/", serveHostByIP)
|
||||
//http.HandleFunc("/", serveHostByIP)
|
||||
|
||||
http.HandleFunc("/configs", uploadConfig)
|
||||
|
||||
http.HandleFunc("/hosts", serveHosts)
|
||||
http.HandleFunc("/hosts/", serveHost)
|
||||
//http.HandleFunc("/hosts/", serveHost)
|
||||
|
||||
http.HandleFunc("/clusters", serveClusters)
|
||||
http.HandleFunc("/clusters/", serveCluster)
|
||||
|
22
cmd/dkl-local-server/ulid.go
Normal file
22
cmd/dkl-local-server/ulid.go
Normal file
@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
ulidp "github.com/oklog/ulid"
|
||||
)
|
||||
|
||||
var (
|
||||
ulidCtx struct{ entropy io.Reader }
|
||||
)
|
||||
|
||||
func initUlid() {
|
||||
entropy := ulidp.Monotonic(rand.New(rand.NewSource(time.Now().UnixNano())), 0)
|
||||
ulidCtx.entropy = entropy
|
||||
}
|
||||
|
||||
func ulid() string {
|
||||
return ulidp.MustNew(ulidp.Now(), ulidCtx.entropy).String()
|
||||
}
|
55
cmd/dkl-local-server/ws-host.go
Normal file
55
cmd/dkl-local-server/ws-host.go
Normal file
@ -0,0 +1,55 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
restful "github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
type wsHost struct {
|
||||
prefix string
|
||||
getHost func(req *restful.Request) string
|
||||
}
|
||||
|
||||
func (ws *wsHost) register(rws *restful.WebService) {
|
||||
for _, what := range []string{
|
||||
"boot.img",
|
||||
"boot.img.gz",
|
||||
"boot.img.lz4",
|
||||
"boot.iso",
|
||||
"boot.tar",
|
||||
"config",
|
||||
"initrd",
|
||||
"ipxe",
|
||||
"kernel",
|
||||
} {
|
||||
rws.Route(rws.GET(ws.prefix + "/" + what).To(ws.render))
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *wsHost) render(req *restful.Request, resp *restful.Response) {
|
||||
hostname := ws.getHost(req)
|
||||
if hostname == "" {
|
||||
http.NotFound(resp.ResponseWriter, req.Request)
|
||||
return
|
||||
}
|
||||
|
||||
cfg, err := readConfig()
|
||||
if err != nil {
|
||||
writeError(resp.ResponseWriter, err)
|
||||
return
|
||||
}
|
||||
|
||||
host := cfg.Host(hostname)
|
||||
if host == nil {
|
||||
log.Print("no host named ", hostname)
|
||||
http.NotFound(resp.ResponseWriter, req.Request)
|
||||
return
|
||||
}
|
||||
|
||||
what := path.Base(req.Request.URL.Path)
|
||||
|
||||
renderHost(resp.ResponseWriter, req.Request, what, host, cfg)
|
||||
}
|
64
cmd/dkl-local-server/ws.go
Normal file
64
cmd/dkl-local-server/ws.go
Normal file
@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
func buildWS() *restful.WebService {
|
||||
ws := &restful.WebService{}
|
||||
|
||||
ws.Route(ws.POST("/configs").To(wsUploadConfig))
|
||||
|
||||
(&wsHost{
|
||||
prefix: "",
|
||||
getHost: detectHost,
|
||||
}).register(ws)
|
||||
|
||||
(&wsHost{
|
||||
prefix: "/hosts/{hostname}",
|
||||
getHost: func(req *restful.Request) string {
|
||||
return req.PathParameter("hostname")
|
||||
},
|
||||
}).register(ws)
|
||||
|
||||
return ws
|
||||
}
|
||||
|
||||
func detectHost(req *restful.Request) string {
|
||||
r := req.Request
|
||||
remoteAddr := r.RemoteAddr
|
||||
|
||||
if *trustXFF {
|
||||
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
|
||||
remoteAddr = strings.Split(xff, ",")[0]
|
||||
}
|
||||
}
|
||||
|
||||
hostIP, _, err := net.SplitHostPort(remoteAddr)
|
||||
|
||||
if err != nil {
|
||||
hostIP = remoteAddr
|
||||
}
|
||||
|
||||
cfg, err := readConfig()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
host := cfg.HostByIP(hostIP)
|
||||
|
||||
if host == nil {
|
||||
log.Print("no host found for IP ", hostIP)
|
||||
return ""
|
||||
}
|
||||
|
||||
return host.Name
|
||||
}
|
||||
|
||||
func wsUploadConfig(req *restful.Request, res *restful.Response) {
|
||||
// TODO
|
||||
}
|
10
go.mod
10
go.mod
@ -4,15 +4,19 @@ require (
|
||||
github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e
|
||||
github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e
|
||||
github.com/coreos/etcd v3.3.11+incompatible // indirect
|
||||
github.com/emicklei/go-restful v2.8.1+incompatible
|
||||
github.com/emicklei/go-restful-openapi v1.0.0
|
||||
github.com/go-openapi/spec v0.18.0 // indirect
|
||||
github.com/gobuffalo/events v1.2.0 // indirect
|
||||
github.com/gobuffalo/meta v0.0.0-20190126124307-c8fb6f4eb5a9 // indirect
|
||||
github.com/gobuffalo/packr v1.21.9 // indirect
|
||||
github.com/gofrs/uuid v3.2.0+incompatible // indirect
|
||||
github.com/google/certificate-transparency-go v1.0.21 // indirect
|
||||
github.com/google/certificate-transparency-go v1.0.21
|
||||
github.com/oklog/ulid v1.3.1
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible
|
||||
github.com/ugorji/go/codec v0.0.0-20190128213124-ee1426cffec0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190129210102-ccddf3741a0c // indirect
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190129210102-ccddf3741a0c
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3
|
||||
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc // indirect
|
||||
golang.org/x/tools v0.0.0-20190130015043-a06a922acc1b // indirect
|
||||
gopkg.in/yaml.v2 v2.2.2
|
||||
|
20
go.sum
20
go.sum
@ -1,5 +1,9 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
@ -24,10 +28,22 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dustin/go-humanize v0.0.0-20180713052910-9f541cc9db5d/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/emicklei/go-restful v2.8.1+incompatible h1:AyDqLHbJ1quqbWr/OWDw+PlIP8ZFoTmYrGYaxzrLbNg=
|
||||
github.com/emicklei/go-restful v2.8.1+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful-openapi v1.0.0 h1:ZFk3RuCl8ZmG1yUAF/mSbXRi5cuyA/k5+EpHayuuTXM=
|
||||
github.com/emicklei/go-restful-openapi v1.0.0/go.mod h1:Q+bHVYfUWv1fvC4FNTsz2AVvFSsXAC7RCiWjF1Sva1A=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonreference v0.17.0 h1:yJW3HCkTHg7NOA+gZ83IPHzUSnUzGXhGmsdiCcMexbA=
|
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/spec v0.18.0 h1:aIjeyG5mo5/FrvDkpKKEGZPmF9MPHahS72mzfVqeQXQ=
|
||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/gobuffalo/buffalo v0.12.8-0.20181004233540-fac9bb505aa8/go.mod h1:sLyT7/dceRXJUxSsE813JTQtA3Eb1vjxWfo/N//vXIY=
|
||||
@ -333,6 +349,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/markbates/deplist v1.0.4/go.mod h1:gRRbPbbuA8TmMiRvaOzUlRfzfjeCCBqX2A6arxN01MM=
|
||||
github.com/markbates/deplist v1.0.5/go.mod h1:gRRbPbbuA8TmMiRvaOzUlRfzfjeCCBqX2A6arxN01MM=
|
||||
github.com/markbates/going v1.0.2/go.mod h1:UWCk3zm0UKefHZ7l8BNqi26UyiEMniznk8naLdTcy6c=
|
||||
@ -368,6 +386,8 @@ github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/monoculum/formam v0.0.0-20180901015400-4e68be1d79ba/go.mod h1:RKgILGEJq24YyJ2ban8EO0RUVSJlF1pGsEvoLEACr/Q=
|
||||
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
|
||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
|
50
pkg/apiutils/apiutils.go
Normal file
50
pkg/apiutils/apiutils.go
Normal file
@ -0,0 +1,50 @@
|
||||
package apiutils
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
)
|
||||
|
||||
// Prepare does the default API preparation.
|
||||
func Prepare() {
|
||||
restful.DefaultRequestContentType(restful.MIME_JSON)
|
||||
restful.DefaultResponseContentType(restful.MIME_JSON)
|
||||
restful.DefaultContainer.Router(restful.CurlyRouter{})
|
||||
}
|
||||
|
||||
// Setup does the default API setup
|
||||
func Setup(addWebServices func()) {
|
||||
Prepare()
|
||||
|
||||
addWebServices()
|
||||
|
||||
SetupHealth()
|
||||
SetupOpenAPI()
|
||||
SetupCORSWildcard()
|
||||
}
|
||||
|
||||
func SetupHealth() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// SetupOpenAPI creates the standard API documentation endpoint at the default location.
|
||||
func SetupOpenAPI() {
|
||||
SetupOpenAPIAt("/swagger.json")
|
||||
}
|
||||
|
||||
// SetupOpenAPI creates the standard API documentation endpoint at the defined location.
|
||||
func SetupOpenAPIAt(apiPath string) {
|
||||
config := restfulspec.Config{
|
||||
WebServices: restful.RegisteredWebServices(),
|
||||
APIPath: apiPath,
|
||||
}
|
||||
restful.Add(restfulspec.NewOpenAPIService(config))
|
||||
}
|
||||
|
||||
func SetupCORSWildcard() {
|
||||
restful.Filter(restful.CrossOriginResourceSharing{
|
||||
CookiesAllowed: true,
|
||||
Container: restful.DefaultContainer,
|
||||
}.Filter)
|
||||
restful.Filter(restful.OPTIONSFilter())
|
||||
}
|
Loading…
Reference in New Issue
Block a user