diff --git a/Dockerfile b/Dockerfile.boltdb similarity index 100% rename from Dockerfile rename to Dockerfile.boltdb diff --git a/Dockerfile.dynamodb b/Dockerfile.dynamodb new file mode 100644 index 0000000..97e8b0b --- /dev/null +++ b/Dockerfile.dynamodb @@ -0,0 +1,35 @@ +FROM node AS ui +WORKDIR /go/metahub +COPY ./ui/package* ./ui/ +RUN cd ui && npm install +COPY ./ui ./ui +COPY ./static ./static +COPY ./templates ./templates +WORKDIR /go/metahub/ui/ +RUN npm run build + +FROM golang:1.12 AS go +WORKDIR /go/metahub +COPY ./go.mod . +COPY ./go.sum . +RUN go mod download +COPY ./cmd ./cmd +COPY ./pkg ./pkg +WORKDIR /go/metahub/cmd/dynamodb +# static build +ENV CGO_ENABLED=0 GOOS=linux +RUN go build -a -ldflags '-extldflags "-static"' . +EXPOSE 8080 + +# Go binary serves the ui web content +FROM ubuntu:18.04 +RUN apt update \ + && apt install -y docker.io vim net-tools +ENV PORT=80 +COPY --from=go /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY --from=ui /go/metahub/static /srv/html/static +COPY --from=ui /go/metahub/templates/gen/index.html /srv/html/ +COPY --from=go /go/metahub/cmd/dynamodb/dynamodb /usr/bin/metahub +VOLUME /data/ +WORKDIR /data/ +CMD ["/usr/bin/metahub"] diff --git a/cmd/boltdb/main.go b/cmd/boltdb/main.go index 080a849..2dc5db3 100644 --- a/cmd/boltdb/main.go +++ b/cmd/boltdb/main.go @@ -4,19 +4,21 @@ import ( "flag" "fmt" "log" - "metahub/pkg/daemon" - registry "metahub/pkg/registry/http/client" - "metahub/pkg/storage/boltdb" "net/http" "os" - "metahub/cmd" + "github.com/qnib/metahub/pkg/daemon" + registry "github.com/qnib/metahub/pkg/registry/http/client" + "github.com/qnib/metahub/pkg/storage/boltdb" + + "github.com/qnib/metahub/cmd" ) var ( version = flag.Bool("version", false, "print version") ) +// Log intercepts each requests and writes it out func Log(handler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL) diff --git a/cmd/dynamodb/main.go b/cmd/dynamodb/main.go new file mode 100644 index 0000000..c710a2d --- /dev/null +++ b/cmd/dynamodb/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "flag" + "fmt" + "log" + "net/http" + "os" + + "github.com/qnib/metahub/pkg/daemon" + + "github.com/qnib/metahub/cmd" + registry "github.com/qnib/metahub/pkg/registry/http/client" + "github.com/qnib/metahub/pkg/storage/dynamodb" +) + +var ( + version = flag.Bool("version", false, "print version") +) + +// Log intercepts each requests and writes it out +func Log(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL) + handler.ServeHTTP(w, r) + }) +} + +func main() { + flag.Parse() + if *version { + fmt.Println(`v0.1.0`) + os.Exit(0) + } + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + + storageService := dynamodb.NewService() + registryService := registry.NewService() + daemonService := daemon.NewService(storageService, registryService) + + router := cmd.RegisterRoutes(daemonService) + + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), Log(router))) +} diff --git a/cmd/gae/gae b/cmd/gae/gae deleted file mode 100755 index 8ace315..0000000 Binary files a/cmd/gae/gae and /dev/null differ diff --git a/cmd/gae/main.go b/cmd/gae/main.go index 94dc1ac..0eb1c40 100644 --- a/cmd/gae/main.go +++ b/cmd/gae/main.go @@ -3,13 +3,13 @@ package main import ( "fmt" "log" - "metahub/pkg/daemon" - registry "metahub/pkg/registry/http/client" - "metahub/pkg/storage/clouddatastore" "net/http" "os" - "metahub/cmd" + "github.com/qnib/metahub/cmd" + "github.com/qnib/metahub/pkg/daemon" + registry "github.com/qnib/metahub/pkg/registry/http/client" + "github.com/qnib/metahub/pkg/storage/clouddatastore" ) func main() { diff --git a/cmd/routes.go b/cmd/routes.go index 958fc9d..564bdf3 100644 --- a/cmd/routes.go +++ b/cmd/routes.go @@ -1,15 +1,16 @@ package cmd import ( - "metahub/pkg/daemon" "net/http" - "metahub/pkg/accounts" - "metahub/pkg/machinetypes" - "metahub/pkg/registry/http/server" + "github.com/qnib/metahub/pkg/daemon" + + "github.com/qnib/metahub/pkg/accounts" + "github.com/qnib/metahub/pkg/machinetypes" + "github.com/qnib/metahub/pkg/registry/http/server" ) -func RegisterRoutes(service daemon.Service) *http.ServeMux{ +func RegisterRoutes(service daemon.Service) *http.ServeMux { router := http.NewServeMux() RegisterStaticRoutes(service, router) RegisterAPIRoutes(service, router) diff --git a/go.mod b/go.mod index 155637e..ff25432 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,10 @@ -module metahub +module github.com/qnib/metahub go 1.12 require ( cloud.google.com/go v0.37.4 + github.com/aws/aws-sdk-go v1.36.19 github.com/boltdb/bolt v1.3.1 github.com/docker/distribution v2.7.0+incompatible github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 // indirect diff --git a/go.sum b/go.sum index 4692dbf..d7df81a 100644 --- a/go.sum +++ b/go.sum @@ -8,11 +8,14 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/aws/aws-sdk-go v1.36.19 h1:zbJZKkxeDiYxUYFjymjWxPye+qa1G2gRVyhIzZrB9zA= +github.com/aws/aws-sdk-go v1.36.19/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.7.0+incompatible h1:neUDAlf3wX6Ml4HdqTrbcOHXtfRN0TFIwt6YFL7N9RU= @@ -56,6 +59,10 @@ github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -75,6 +82,7 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -93,6 +101,7 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -100,6 +109,7 @@ go.opencensus.io v0.20.1 h1:pMEjRZ1M4ebWGikflH7nQpV6+Zr88KBMA2XJD3sbijw= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -113,6 +123,9 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -128,11 +141,17 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -149,10 +168,13 @@ google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3 google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/accounts/auth_middleware.go b/pkg/accounts/auth_middleware.go index b4593af..baff871 100644 --- a/pkg/accounts/auth_middleware.go +++ b/pkg/accounts/auth_middleware.go @@ -3,10 +3,11 @@ package accounts import ( "fmt" "log" - "metahub/pkg/daemon" "net/http" "strings" + "github.com/qnib/metahub/pkg/daemon" + "github.com/gorilla/context" ) diff --git a/pkg/accounts/github_handler.go b/pkg/accounts/github_handler.go index 97ac71f..386d4f2 100644 --- a/pkg/accounts/github_handler.go +++ b/pkg/accounts/github_handler.go @@ -4,9 +4,10 @@ import ( "context" "fmt" "log" - "metahub/pkg/daemon" "net/http" + "github.com/qnib/metahub/pkg/daemon" + "github.com/google/go-github/github" "golang.org/x/oauth2" githuboauth "golang.org/x/oauth2/github" diff --git a/pkg/accounts/google_handler.go b/pkg/accounts/google_handler.go index 1122e5a..58a964f 100644 --- a/pkg/accounts/google_handler.go +++ b/pkg/accounts/google_handler.go @@ -5,10 +5,11 @@ import ( "encoding/json" "fmt" "io/ioutil" - "metahub/pkg/daemon" "net/http" "strings" + "github.com/qnib/metahub/pkg/daemon" + "golang.org/x/oauth2" googleAuth "golang.org/x/oauth2/google" ) diff --git a/pkg/accounts/handler_base.go b/pkg/accounts/handler_base.go index 2271fd8..fffb9cf 100644 --- a/pkg/accounts/handler_base.go +++ b/pkg/accounts/handler_base.go @@ -4,10 +4,11 @@ import ( "context" "encoding/json" "log" - "metahub/pkg/daemon" - "metahub/pkg/storage" "net/http" + "github.com/qnib/metahub/pkg/daemon" + "github.com/qnib/metahub/pkg/storage" + "golang.org/x/oauth2" ) diff --git a/pkg/accounts/identity_handler.go b/pkg/accounts/identity_handler.go index edfb3ec..cfe56c3 100644 --- a/pkg/accounts/identity_handler.go +++ b/pkg/accounts/identity_handler.go @@ -3,10 +3,11 @@ package accounts import ( "encoding/json" "log" - "metahub/pkg/daemon" - "metahub/pkg/storage" "net/http" + "github.com/qnib/metahub/pkg/daemon" + "github.com/qnib/metahub/pkg/storage" + "github.com/gorilla/context" ) diff --git a/pkg/accounts/router.go b/pkg/accounts/router.go index e2a5cd0..78d3d7d 100644 --- a/pkg/accounts/router.go +++ b/pkg/accounts/router.go @@ -3,7 +3,7 @@ package accounts import ( "net/http" - "metahub/pkg/daemon" + "github.com/qnib/metahub/pkg/daemon" "github.com/gorilla/mux" ) diff --git a/pkg/daemon/service.go b/pkg/daemon/service.go index 7bf6205..768d02c 100644 --- a/pkg/daemon/service.go +++ b/pkg/daemon/service.go @@ -1,8 +1,8 @@ package daemon import ( - "metahub/pkg/registry" - "metahub/pkg/storage" + "github.com/qnib/metahub/pkg/registry" + "github.com/qnib/metahub/pkg/storage" ) // Service is the main interface to other execution services diff --git a/pkg/machinetypes/add_handler.go b/pkg/machinetypes/add_handler.go index f032d98..7361439 100644 --- a/pkg/machinetypes/add_handler.go +++ b/pkg/machinetypes/add_handler.go @@ -3,10 +3,11 @@ package machinetypes import ( "encoding/json" "log" - "metahub/pkg/daemon" "net/http" - "metahub/pkg/storage" + "github.com/qnib/metahub/pkg/daemon" + + "github.com/qnib/metahub/pkg/storage" "github.com/gorilla/context" ) @@ -39,7 +40,7 @@ func getAddHandler(service daemon.Service) http.Handler { log.Printf("failed adding machine type: %v", err) w.WriteHeader(http.StatusInternalServerError) return - } + } d, err := json.Marshal(mt) if err != nil { diff --git a/pkg/machinetypes/auth_middleware.go b/pkg/machinetypes/auth_middleware.go index f1e31d9..e23eb42 100644 --- a/pkg/machinetypes/auth_middleware.go +++ b/pkg/machinetypes/auth_middleware.go @@ -3,11 +3,12 @@ package machinetypes import ( "fmt" "log" - "metahub/pkg/daemon" - "metahub/pkg/registry/filter" "net/http" "os" + "github.com/qnib/metahub/pkg/daemon" + "github.com/qnib/metahub/pkg/registry/filter" + "github.com/gorilla/context" ) diff --git a/pkg/machinetypes/delete_handler.go b/pkg/machinetypes/delete_handler.go index 8b302fd..2a6eebe 100644 --- a/pkg/machinetypes/delete_handler.go +++ b/pkg/machinetypes/delete_handler.go @@ -3,9 +3,10 @@ package machinetypes import ( "encoding/json" "log" - "metahub/pkg/daemon" "net/http" + "github.com/qnib/metahub/pkg/daemon" + "github.com/gorilla/context" ) diff --git a/pkg/machinetypes/get_handler.go b/pkg/machinetypes/get_handler.go index b5bfadb..f59c5f0 100644 --- a/pkg/machinetypes/get_handler.go +++ b/pkg/machinetypes/get_handler.go @@ -3,10 +3,11 @@ package machinetypes import ( "encoding/json" "log" - "metahub/pkg/daemon" "net/http" "strconv" + "github.com/qnib/metahub/pkg/daemon" + "github.com/gorilla/context" ) diff --git a/pkg/machinetypes/list_handler.go b/pkg/machinetypes/list_handler.go index b3feb68..361bb7e 100644 --- a/pkg/machinetypes/list_handler.go +++ b/pkg/machinetypes/list_handler.go @@ -3,10 +3,11 @@ package machinetypes import ( "encoding/json" "log" - "metahub/pkg/daemon" - "metahub/pkg/storage" "net/http" + "github.com/qnib/metahub/pkg/daemon" + "github.com/qnib/metahub/pkg/storage" + "github.com/gorilla/context" ) diff --git a/pkg/machinetypes/router.go b/pkg/machinetypes/router.go index 1653e9e..e24792a 100644 --- a/pkg/machinetypes/router.go +++ b/pkg/machinetypes/router.go @@ -3,8 +3,8 @@ package machinetypes import ( "net/http" - auth "metahub/pkg/accounts" - "metahub/pkg/daemon" + auth "github.com/qnib/metahub/pkg/accounts" + "github.com/qnib/metahub/pkg/daemon" "github.com/gorilla/mux" ) @@ -18,5 +18,5 @@ func NewRouter(service daemon.Service, pathPrefix string) http.Handler { router.Handle(pathPrefix+"/list", getListHandler(service)).Methods("GET") router.Handle(pathPrefix+"/delete", getDeleteHandler(service)).Methods("POST") router.Handle(pathPrefix+"/update", getUpdateHandler(service)).Methods("POST") - return router + return router } diff --git a/pkg/machinetypes/update_handler.go b/pkg/machinetypes/update_handler.go index fd73a58..a735a38 100644 --- a/pkg/machinetypes/update_handler.go +++ b/pkg/machinetypes/update_handler.go @@ -3,10 +3,11 @@ package machinetypes import ( "encoding/json" "log" - "metahub/pkg/daemon" - "metahub/pkg/storage" "net/http" + "github.com/qnib/metahub/pkg/daemon" + "github.com/qnib/metahub/pkg/storage" + "github.com/gorilla/context" ) diff --git a/pkg/registry/filter/service.go b/pkg/registry/filter/service.go index 6ba9dcc..f856dd1 100644 --- a/pkg/registry/filter/service.go +++ b/pkg/registry/filter/service.go @@ -5,8 +5,9 @@ import ( "fmt" "io" "log" - "metahub/pkg/registry" - "metahub/pkg/storage" + + "github.com/qnib/metahub/pkg/registry" + "github.com/qnib/metahub/pkg/storage" "github.com/docker/distribution" "github.com/opencontainers/go-digest" diff --git a/pkg/registry/http/client/service.go b/pkg/registry/http/client/service.go index 2e4e6fa..3e6f4ef 100644 --- a/pkg/registry/http/client/service.go +++ b/pkg/registry/http/client/service.go @@ -4,7 +4,8 @@ import ( "context" "fmt" "io" - "metahub/pkg/registry" + + "github.com/qnib/metahub/pkg/registry" "github.com/docker/distribution" "github.com/docker/distribution/reference" diff --git a/pkg/registry/http/server/base_handler.go b/pkg/registry/http/server/base_handler.go index e1baaff..e98adec 100644 --- a/pkg/registry/http/server/base_handler.go +++ b/pkg/registry/http/server/base_handler.go @@ -1,8 +1,9 @@ package server import ( - "metahub/pkg/daemon" "net/http" + + "github.com/qnib/metahub/pkg/daemon" ) func getBaseHandler(service daemon.Service) http.Handler { diff --git a/pkg/registry/http/server/blobs_handler.go b/pkg/registry/http/server/blobs_handler.go index 6bdbf44..1cf7163 100644 --- a/pkg/registry/http/server/blobs_handler.go +++ b/pkg/registry/http/server/blobs_handler.go @@ -3,11 +3,12 @@ package server import ( "io" "log" - "metahub/pkg/daemon" - "metahub/pkg/registry" "net/http" "strconv" + "github.com/qnib/metahub/pkg/daemon" + "github.com/qnib/metahub/pkg/registry" + "github.com/gorilla/context" "github.com/gorilla/mux" digest "github.com/opencontainers/go-digest" diff --git a/pkg/registry/http/server/manifests_handler.go b/pkg/registry/http/server/manifests_handler.go index bd33982..830ccc0 100644 --- a/pkg/registry/http/server/manifests_handler.go +++ b/pkg/registry/http/server/manifests_handler.go @@ -3,10 +3,11 @@ package server import ( "fmt" "log" - "metahub/pkg/daemon" - "metahub/pkg/registry" "net/http" + "github.com/qnib/metahub/pkg/daemon" + "github.com/qnib/metahub/pkg/registry" + "github.com/gorilla/context" manifestListSchema "github.com/docker/distribution/manifest/manifestlist" diff --git a/pkg/registry/http/server/router.go b/pkg/registry/http/server/router.go index fca06cf..2c178fa 100644 --- a/pkg/registry/http/server/router.go +++ b/pkg/registry/http/server/router.go @@ -1,10 +1,11 @@ package server import ( - "metahub/pkg/daemon" - "metahub/pkg/machinetypes" "net/http" + "github.com/qnib/metahub/pkg/daemon" + "github.com/qnib/metahub/pkg/machinetypes" + "github.com/gorilla/mux" ) diff --git a/pkg/storage/boltdb/accesstoken_service.go b/pkg/storage/boltdb/accesstoken_service.go index 2347f05..d7d6683 100644 --- a/pkg/storage/boltdb/accesstoken_service.go +++ b/pkg/storage/boltdb/accesstoken_service.go @@ -2,13 +2,13 @@ package boltdb import ( "context" - "metahub/pkg/storage" "time" -) + "github.com/qnib/metahub/pkg/storage" +) type accessTokenService struct { - ctx context.Context + ctx context.Context } func (s *accessTokenService) Get(token string) (*storage.AccessToken, error) { diff --git a/pkg/storage/boltdb/account_service.go b/pkg/storage/boltdb/account_service.go index 1fe8f9d..497574c 100644 --- a/pkg/storage/boltdb/account_service.go +++ b/pkg/storage/boltdb/account_service.go @@ -2,11 +2,12 @@ package boltdb import ( "context" - "metahub/pkg/storage" + + "github.com/qnib/metahub/pkg/storage" ) type accountService struct { - ctx context.Context + ctx context.Context } func (s *accountService) Upsert(name string, a storage.Account) error { diff --git a/pkg/storage/boltdb/dummies.go b/pkg/storage/boltdb/dummies.go index 98e0eca..c4bca68 100644 --- a/pkg/storage/boltdb/dummies.go +++ b/pkg/storage/boltdb/dummies.go @@ -1,41 +1,41 @@ package boltdb -import "metahub/pkg/storage" +import "github.com/qnib/metahub/pkg/storage" // Consts for protoype const ( - user = "qnib" + user = "qnib" accountName = user ) // Dummy MachineTypes var ( mType1 = storage.MachineType{ - ID : 1, - DisplayName : "type1", - Features : []string{"cpu:broadwell"}, - Login : user+"-type1", - Password : user+"-type1", + ID: 1, + DisplayName: "type1", + Features: []string{"cpu:broadwell"}, + Login: user + "-type1", + Password: user + "-type1", } mType2 = storage.MachineType{ - ID : 2, - DisplayName : "type2", - Features : []string{"cpu:skylake"}, - Login : user+"-type2", - Password : user+"-type2", + ID: 2, + DisplayName: "type2", + Features: []string{"cpu:skylake"}, + Login: user + "-type2", + Password: user + "-type2", } mType3 = storage.MachineType{ - ID : 3, - DisplayName : "type3", - Features : []string{"cpu:coffelake"}, - Login : user+"-type3", - Password : user+"-type3", + ID: 3, + DisplayName: "type3", + Features: []string{"cpu:coffelake"}, + Login: user + "-type3", + Password: user + "-type3", } mType4 = storage.MachineType{ - ID : 4, - DisplayName : "type4", - Features : []string{"cpu:broadwell","nvcap:5.2"}, - Login : user+"-type4", - Password : user+"-type4", + ID: 4, + DisplayName: "type4", + Features: []string{"cpu:broadwell", "nvcap:5.2"}, + Login: user + "-type4", + Password: user + "-type4", } ) diff --git a/pkg/storage/boltdb/machinetype_service.go b/pkg/storage/boltdb/machinetype_service.go index b44b307..2ea84d8 100644 --- a/pkg/storage/boltdb/machinetype_service.go +++ b/pkg/storage/boltdb/machinetype_service.go @@ -5,9 +5,10 @@ import ( "encoding/json" "fmt" "log" - "metahub/pkg/storage" "os" + "github.com/qnib/metahub/pkg/storage" + "github.com/boltdb/bolt" ) diff --git a/pkg/storage/boltdb/service.go b/pkg/storage/boltdb/service.go index df95b4b..d3a8b7e 100644 --- a/pkg/storage/boltdb/service.go +++ b/pkg/storage/boltdb/service.go @@ -4,18 +4,18 @@ import ( "context" "fmt" "log" - "metahub/pkg/storage" "os" "sync" - "github.com/boltdb/bolt" + "github.com/boltdb/bolt" + "github.com/qnib/metahub/pkg/storage" ) var db *bolt.DB var dbSync sync.Mutex func init() { - if _, b := os.LookupEnv("STATIC_MACHINES");b { + if _, b := os.LookupEnv("STATIC_MACHINES"); b { log.Println("Environment STATIC_MACHINES is set: Serve static machine type") } else { err := setupDB() @@ -35,19 +35,19 @@ type service struct { func (s *service) MachineTypeService(ctx context.Context) (storage.MachineTypeService, error) { return &machineTypeService{ - ctx: ctx, + ctx: ctx, }, nil } func (s *service) AccessTokenService(ctx context.Context) (storage.AccessTokenService, error) { return &accessTokenService{ - ctx: ctx, + ctx: ctx, }, nil } func (s *service) AccountService(ctx context.Context) (storage.AccountService, error) { return &accountService{ - ctx: ctx, + ctx: ctx, }, nil } @@ -81,4 +81,3 @@ func setupDB() error { fmt.Println("DB Setup Done") return nil } - diff --git a/pkg/storage/clouddatastore/accesstoken_service.go b/pkg/storage/clouddatastore/accesstoken_service.go index 59fb1c1..8f73fa2 100644 --- a/pkg/storage/clouddatastore/accesstoken_service.go +++ b/pkg/storage/clouddatastore/accesstoken_service.go @@ -3,7 +3,8 @@ package clouddatastore import ( "context" "fmt" - "metahub/pkg/storage" + + "github.com/qnib/metahub/pkg/storage" "cloud.google.com/go/datastore" ) diff --git a/pkg/storage/clouddatastore/account_service.go b/pkg/storage/clouddatastore/account_service.go index 62b8f6f..2a4fa2e 100644 --- a/pkg/storage/clouddatastore/account_service.go +++ b/pkg/storage/clouddatastore/account_service.go @@ -3,7 +3,8 @@ package clouddatastore import ( "context" "fmt" - "metahub/pkg/storage" + + "github.com/qnib/metahub/pkg/storage" "cloud.google.com/go/datastore" ) diff --git a/pkg/storage/clouddatastore/machinetype_service.go b/pkg/storage/clouddatastore/machinetype_service.go index e7d4efc..7544a49 100644 --- a/pkg/storage/clouddatastore/machinetype_service.go +++ b/pkg/storage/clouddatastore/machinetype_service.go @@ -3,9 +3,10 @@ package clouddatastore import ( "context" "fmt" - "metahub/pkg/storage" "sort" + "cloud.google.com/go/datastore" + "github.com/qnib/metahub/pkg/storage" ) type machineTypeService struct { @@ -44,7 +45,7 @@ func (s *machineTypeService) GetByUsername(username string) (*storage.MachineTyp var machineTypes []machineTypeModel q := datastore.NewQuery(machineTypeEntityKind) - q=q.Filter("login =",username) + q = q.Filter("login =", username) machineTypeKeys, err := s.client.GetAll(s.ctx, q, &machineTypes) if _, ok := err.(*datastore.ErrFieldMismatch); ok { err = nil @@ -53,28 +54,28 @@ func (s *machineTypeService) GetByUsername(username string) (*storage.MachineTyp return nil, fmt.Errorf("error querying feature sets: %v", err) } - if len(machineTypeKeys)==0{ + if len(machineTypeKeys) == 0 { return nil, nil } - if len(machineTypeKeys)>1{ - return nil, fmt.Errorf("found %d entities",len(machineTypeKeys)) + if len(machineTypeKeys) > 1 { + return nil, fmt.Errorf("found %d entities", len(machineTypeKeys)) } - mt:=machineTypes[0] - machineTypeKey:=machineTypeKeys[0] + mt := machineTypes[0] + machineTypeKey := machineTypeKeys[0] -/* machineTypeKey, err := datastore.DecodeKey(username) - var mt machineTypeModel - err = s.client.Get(s.ctx, machineTypeKey, &mt) - if _, ok := err.(*datastore.ErrFieldMismatch); ok { - err = nil - } - if err == datastore.ErrNoSuchEntity { - return nil, nil - } - if err != nil { - return nil, fmt.Errorf("error getting machine type: %v", err) - }*/ + /* machineTypeKey, err := datastore.DecodeKey(username) + var mt machineTypeModel + err = s.client.Get(s.ctx, machineTypeKey, &mt) + if _, ok := err.(*datastore.ErrFieldMismatch); ok { + err = nil + } + if err == datastore.ErrNoSuchEntity { + return nil, nil + } + if err != nil { + return nil, fmt.Errorf("error getting machine type: %v", err) + }*/ return &storage.MachineType{ ID: machineTypeKey.ID, DisplayName: mt.DisplayName, @@ -86,9 +87,9 @@ func (s *machineTypeService) GetByUsername(username string) (*storage.MachineTyp func (s *machineTypeService) Add(accountName string, mt *storage.MachineType) error { - if existingMt,err:=s.GetByUsername(mt.Login);err != nil { + if existingMt, err := s.GetByUsername(mt.Login); err != nil { return fmt.Errorf("failed to check for existing login: %v", err) - }else if existingMt!=nil{ + } else if existingMt != nil { return fmt.Errorf("login already exist: %v", err) } @@ -138,12 +139,12 @@ func (s *machineTypeService) List(accountName string) ([]storage.MachineType, er result := make([]storage.MachineType, len(machineTypes)) - sort.Slice(machineTypes, func(i, j int) bool { + sort.Slice(machineTypes, func(i, j int) bool { return machineTypes[i].DisplayName < machineTypes[j].DisplayName - }) - sort.Slice(machineTypeKeys, func(i, j int) bool { + }) + sort.Slice(machineTypeKeys, func(i, j int) bool { return machineTypes[i].DisplayName < machineTypes[j].DisplayName - }) + }) for i, mt := range machineTypes { k := machineTypeKeys[i] @@ -171,10 +172,10 @@ func (s *machineTypeService) Update(accountName string, mt storage.MachineType) return fmt.Errorf("error getting entity: %v", err) } - if tmp.Login != mt.Login{ - if existingMt,err:=s.GetByUsername(mt.Login);err != nil { + if tmp.Login != mt.Login { + if existingMt, err := s.GetByUsername(mt.Login); err != nil { return fmt.Errorf("failed to check for existing login: %v", err) - }else if existingMt!=nil{ + } else if existingMt != nil { return fmt.Errorf("login already exist: %v", err) } } diff --git a/pkg/storage/clouddatastore/service.go b/pkg/storage/clouddatastore/service.go index ca3712c..1acb605 100644 --- a/pkg/storage/clouddatastore/service.go +++ b/pkg/storage/clouddatastore/service.go @@ -3,7 +3,8 @@ package clouddatastore import ( "context" "fmt" - "metahub/pkg/storage" + + "github.com/qnib/metahub/pkg/storage" "cloud.google.com/go/datastore" ) diff --git a/pkg/storage/dynamodb/accesstoken_model.go b/pkg/storage/dynamodb/accesstoken_model.go new file mode 100644 index 0000000..772a8fc --- /dev/null +++ b/pkg/storage/dynamodb/accesstoken_model.go @@ -0,0 +1,12 @@ +package dynamodb + +import ( + "time" +) + +var accessTokenEntityKind = "access_token" + +type accessToken struct { + AccountName string `datastore:"account,noindex"` + Expiry time.Time `datastore:"expiry,omitempty"` +} diff --git a/pkg/storage/dynamodb/accesstoken_service.go b/pkg/storage/dynamodb/accesstoken_service.go new file mode 100644 index 0000000..04e5ec7 --- /dev/null +++ b/pkg/storage/dynamodb/accesstoken_service.go @@ -0,0 +1,24 @@ +package dynamodb + +import ( + "context" + "time" + + "github.com/qnib/metahub/pkg/storage" +) + +type accessTokenService struct { + ctx context.Context +} + +func (s *accessTokenService) Get(token string) (*storage.AccessToken, error) { + //TODO: check at.Expiry? + return &storage.AccessToken{ + AccountName: token, + Expiry: time.Time{}, + }, nil +} + +func (s *accessTokenService) Put(token string, at storage.AccessToken) error { + return nil +} diff --git a/pkg/storage/dynamodb/account_model.go b/pkg/storage/dynamodb/account_model.go new file mode 100644 index 0000000..53cdda4 --- /dev/null +++ b/pkg/storage/dynamodb/account_model.go @@ -0,0 +1,7 @@ +package dynamodb + +var accountEntityKind = "account" + +type account struct { + DisplayName string `datastore:"name,noindex"` +} diff --git a/pkg/storage/dynamodb/account_service.go b/pkg/storage/dynamodb/account_service.go new file mode 100644 index 0000000..223fe95 --- /dev/null +++ b/pkg/storage/dynamodb/account_service.go @@ -0,0 +1,21 @@ +package dynamodb + +import ( + "context" + + "github.com/qnib/metahub/pkg/storage" +) + +type accountService struct { + ctx context.Context +} + +func (s *accountService) Upsert(name string, a storage.Account) error { + return nil +} + +func (s *accountService) Get(name string) (*storage.Account, error) { + return &storage.Account{ + DisplayName: name, + }, nil +} diff --git a/pkg/storage/dynamodb/dummies.go b/pkg/storage/dynamodb/dummies.go new file mode 100644 index 0000000..09c967e --- /dev/null +++ b/pkg/storage/dynamodb/dummies.go @@ -0,0 +1,41 @@ +package dynamodb + +import "github.com/qnib/metahub/pkg/storage" + +// Consts for protoype +const ( + user = "qnib" + accountName = user +) + +// Dummy MachineTypes +var ( + mType1 = storage.MachineType{ + ID: 1, + DisplayName: "type1", + Features: []string{"cpu:broadwell"}, + Login: user + "-type1", + Password: user + "-type1", + } + mType2 = storage.MachineType{ + ID: 2, + DisplayName: "type2", + Features: []string{"cpu:skylake"}, + Login: user + "-type2", + Password: user + "-type2", + } + mType3 = storage.MachineType{ + ID: 3, + DisplayName: "type3", + Features: []string{"cpu:coffelake"}, + Login: user + "-type3", + Password: user + "-type3", + } + mType4 = storage.MachineType{ + ID: 4, + DisplayName: "type4", + Features: []string{"cpu:broadwell", "nvcap:5.2"}, + Login: user + "-type4", + Password: user + "-type4", + } +) diff --git a/pkg/storage/dynamodb/machinetype_model.go b/pkg/storage/dynamodb/machinetype_model.go new file mode 100644 index 0000000..b2e00f7 --- /dev/null +++ b/pkg/storage/dynamodb/machinetype_model.go @@ -0,0 +1,10 @@ +package dynamodb + +var machineTypeEntityKind = "MachineType" + +type machineTypeModel struct { + DisplayName string `datastore:"name,noindex"` + Features []string `datastore:"features,noindex"` + Login string `datastore:"login"` + Password string `datastore:"password,noindex"` +} diff --git a/pkg/storage/dynamodb/machinetype_service.go b/pkg/storage/dynamodb/machinetype_service.go new file mode 100644 index 0000000..ef1fe7c --- /dev/null +++ b/pkg/storage/dynamodb/machinetype_service.go @@ -0,0 +1,77 @@ +package dynamodb + +import ( + "context" + "fmt" + "log" + "strings" + + "github.com/qnib/metahub/pkg/storage" +) + +type machineTypeService struct { + ctx context.Context +} + +func formatLogin(accountName string, login string) { + +} + +func (s *machineTypeService) GetByID(accountName string, id int64) (mt *storage.MachineType, err error) { + log.Printf("GetByID(%s, %d)\n", accountName, id) + return mt, err +} + +/*** GetByUsername will be used to authenticate a client. +We'll chop off the prefix (e.g. qnib from qnib-c518xl-shp2) and chat the prefix against the users table +*/ +func (s *machineTypeService) GetByUsername(username string) (mt *storage.MachineType, err error) { + log.Printf("GetByUsername(%s)\n", username) + // Chop of the first part of the usrename, without the type specific suffixes + userSplit := strings.Split(username, "-") + if len(userSplit) == 1 { + err = fmt.Errorf("username should contain the actual user seperated by a dash (e.g. qnib-type1). Got: %s", username) + return + } + usern := userSplit[0] + user, err := mhTableUserScan(svc, fmt.Sprintf("%s_users", mhDbTablePrefix), usern) + if err != nil { + return + } + log.Println("Found item:") + log.Println("Login: ", user.Login) + log.Println("Password: ", user.Password) + mt = &storage.MachineType{ + Login: user.Login, + Password: user.Password, + } + typen := strings.Join(userSplit[1:], "-") + typ, err := mhTableTypeScan(svc, fmt.Sprintf("%s_types", mhDbTablePrefix), typen) + if err != nil { + return + } + log.Println("Found item:") + log.Println("Type: ", typ.Type) + log.Println("Featuresd: ", typ.Features) + mt.Features = strings.Split(typ.Features, ",") + mt.DisplayName = typ.Type + log.Printf("Return MT: %v", mt) + return +} + +func (s *machineTypeService) Add(accountName string, mt *storage.MachineType) (err error) { + return err +} + +func (s *machineTypeService) Delete(accountName string, id int64) error { + return nil +} + +func (s *machineTypeService) List(accountName string) (mt []storage.MachineType, err error) { + log.Printf("mt.List(accountName=%s)", accountName) + return +} + +func (s *machineTypeService) Update(accountName string, mt storage.MachineType) (err error) { + return err +} diff --git a/pkg/storage/dynamodb/service.go b/pkg/storage/dynamodb/service.go new file mode 100644 index 0000000..afd6082 --- /dev/null +++ b/pkg/storage/dynamodb/service.go @@ -0,0 +1,237 @@ +package dynamodb + +import ( + "context" + "fmt" + "log" + "sync" + + "github.com/qnib/metahub/pkg/storage" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" +) + +var ( + svc *dynamodb.DynamoDB + dbSync sync.Mutex +) + +const ( + mhDbTablePrefix = "metahub-v1" +) + +func init() { + err := setupDB() + if err != nil { + log.Fatal(err.Error()) + } +} + +// NewService returns a new storage.Service for boltdb +func NewService() storage.Service { + return &service{} +} + +type service struct{} + +func (s *service) MachineTypeService(ctx context.Context) (storage.MachineTypeService, error) { + return &machineTypeService{ + ctx: ctx, + }, nil +} + +func (s *service) AccessTokenService(ctx context.Context) (storage.AccessTokenService, error) { + return &accessTokenService{ + ctx: ctx, + }, nil +} + +func (s *service) AccountService(ctx context.Context) (storage.AccountService, error) { + return &accountService{ + ctx: ctx, + }, nil +} + +func setupDB() (err error) { + dbSync.Lock() + defer dbSync.Unlock() + sess := session.Must(session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + })) + + // Create DynamoDB client + svc = dynamodb.New(sess) + if !mhTableExists(svc, fmt.Sprintf("%s_types", mhDbTablePrefix)) { + err = mhTableTypesCreate(svc) + if err != nil { + log.Fatal(err.Error()) + } + } + if !mhTableExists(svc, fmt.Sprintf("%s_users", mhDbTablePrefix)) { + err = mhTableUsersCreate(svc) + if err != nil { + log.Fatal(err.Error()) + } + err = mhTableInit(svc) + } + + fmt.Println("DB Setup Done") + return +} + +func mhTableExists(db *dynamodb.DynamoDB, mhDbTable string) bool { + input := &dynamodb.ListTablesInput{} + for { + // Get the list of tables + result, err := db.ListTables(input) + if err != nil { + if aerr, ok := err.(awserr.Error); ok { + switch aerr.Code() { + case dynamodb.ErrCodeInternalServerError: + log.Println(dynamodb.ErrCodeInternalServerError, aerr.Error()) + default: + log.Println(aerr.Error()) + } + } else { + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + } + } + for _, n := range result.TableNames { + // if we already find the table we are looking for - awesome + // -> otherwise rember we need to create it. + log.Printf("Table found: %s\n", *n) + if *n == mhDbTable { + return true + } + + } + // assign the last read tablename as the start for our next call to the ListTables function + // the maximum number of table names returned in a call is 100 (default), which requires us to make + // multiple calls to the ListTables function to retrieve all table names + input.ExclusiveStartTableName = result.LastEvaluatedTableName + if result.LastEvaluatedTableName == nil { + break + } + } + return false +} + +func mhTableInit(db *dynamodb.DynamoDB) (err error) { + return +} + +func mhTableUsersCreate(db *dynamodb.DynamoDB) (err error) { + mhDbTable := fmt.Sprintf("%s_users", mhDbTablePrefix) + input := &dynamodb.CreateTableInput{ + AttributeDefinitions: GetUsersAttrDefs(), + KeySchema: GetUsersAttrSchemas(), + ProvisionedThroughput: &dynamodb.ProvisionedThroughput{ + ReadCapacityUnits: aws.Int64(10), + WriteCapacityUnits: aws.Int64(10), + }, + TableName: aws.String(mhDbTable), + } + + _, err = db.CreateTable(input) + if err != nil { + fmt.Println("Got error calling CreateTable:") + fmt.Println(err.Error()) + } + fmt.Println("Created the table", mhDbTable) + return +} + +func mhTableTypesCreate(db *dynamodb.DynamoDB) (err error) { + mhDbTable := fmt.Sprintf("%s_types", mhDbTablePrefix) + input := &dynamodb.CreateTableInput{ + AttributeDefinitions: GetTypesAttrDefs(), + KeySchema: GetTypesAttrSchemas(), + ProvisionedThroughput: &dynamodb.ProvisionedThroughput{ + ReadCapacityUnits: aws.Int64(10), + WriteCapacityUnits: aws.Int64(10), + }, + TableName: aws.String(mhDbTable), + } + + _, err = db.CreateTable(input) + if err != nil { + fmt.Println("Got error calling CreateTable:") + fmt.Println(err.Error()) + } + fmt.Println("Created the table", mhDbTable) + return +} + +func mhTableUserScan(db *dynamodb.DynamoDB, tableName, usern string) (user UsersItem, err error) { + log.Printf("Search for username '%s' in '%s'", usern, tableName) + var queryInput = &dynamodb.QueryInput{ + TableName: aws.String(tableName), + KeyConditions: map[string]*dynamodb.Condition{ + "Login": { + ComparisonOperator: aws.String("EQ"), + AttributeValueList: []*dynamodb.AttributeValue{ + { + S: aws.String(usern), + }, + }, + }, + }, + } + result, err := db.Query(queryInput) + if err != nil { + fmt.Println(err.Error()) + return + } + userObj := []UsersItem{} + err = dynamodbattribute.UnmarshalListOfMaps(result.Items, &userObj) + + switch len(userObj) { + case 0: + err = fmt.Errorf("Could not find user: '%s'", usern) + case 1: + user = userObj[0] + default: + err = fmt.Errorf("Found multiple users for '%s'? WTF?", usern) + } + return +} + +func mhTableTypeScan(db *dynamodb.DynamoDB, tableName, typen string) (typeItem TypeItem, err error) { + log.Printf("Search for type '%s' in '%s'", typen, tableName) + var queryInput = &dynamodb.QueryInput{ + TableName: aws.String(tableName), + KeyConditions: map[string]*dynamodb.Condition{ + "Type": { + ComparisonOperator: aws.String("EQ"), + AttributeValueList: []*dynamodb.AttributeValue{ + { + S: aws.String(typen), + }, + }, + }, + }, + } + result, err := db.Query(queryInput) + if err != nil { + fmt.Println(err.Error()) + return + } + typeObj := []TypeItem{} + err = dynamodbattribute.UnmarshalListOfMaps(result.Items, &typeObj) + + switch len(typeObj) { + case 0: + err = fmt.Errorf("Could not find type: '%s'", typen) + case 1: + typeItem = typeObj[0] + default: + err = fmt.Errorf("Found multiple types for '%s'? WTF?", typen) + } + return +} diff --git a/pkg/storage/dynamodb/types.go b/pkg/storage/dynamodb/types.go new file mode 100644 index 0000000..ca0233b --- /dev/null +++ b/pkg/storage/dynamodb/types.go @@ -0,0 +1,34 @@ +package dynamodb + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/dynamodb" +) + +// GetTypesAttrDefs returns the definitions +func GetTypesAttrDefs() []*dynamodb.AttributeDefinition { + return []*dynamodb.AttributeDefinition{{ + AttributeName: aws.String("Type"), + AttributeType: aws.String("S"), + }, { + AttributeName: aws.String("Features"), + AttributeType: aws.String("S"), + }} +} + +// GetTypesAttrSchemas returns the schemas +func GetTypesAttrSchemas() []*dynamodb.KeySchemaElement { + return []*dynamodb.KeySchemaElement{{ + AttributeName: aws.String("Type"), + KeyType: aws.String("HASH"), + }, { + AttributeName: aws.String("Features"), + KeyType: aws.String("RANGE"), + }} +} + +// TypesItem holds the features for a particular type of client +type TypeItem struct { + Type string + Features string +} diff --git a/pkg/storage/dynamodb/users.go b/pkg/storage/dynamodb/users.go new file mode 100644 index 0000000..4d85b43 --- /dev/null +++ b/pkg/storage/dynamodb/users.go @@ -0,0 +1,34 @@ +package dynamodb + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/dynamodb" +) + +// GetUsersAttrDefs returns the definitions +func GetUsersAttrDefs() []*dynamodb.AttributeDefinition { + return []*dynamodb.AttributeDefinition{{ + AttributeName: aws.String("Login"), + AttributeType: aws.String("S"), + }, { + AttributeName: aws.String("Password"), + AttributeType: aws.String("S"), + }} +} + +// GetUsersAttrSchemas returns the schemas +func GetUsersAttrSchemas() []*dynamodb.KeySchemaElement { + return []*dynamodb.KeySchemaElement{{ + AttributeName: aws.String("Login"), + KeyType: aws.String("HASH"), + }, { + AttributeName: aws.String("Password"), + KeyType: aws.String("RANGE"), + }} +} + +// UsersItem holds the features for a particular login +type UsersItem struct { + Login string + Password string +}