mirror of https://github.com/portainer/portainer
feat(database): initial commit
parent
cc487ae68a
commit
3e0ec6a379
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/portainer/portainer/api/cli"
|
||||
"github.com/portainer/portainer/api/cron"
|
||||
"github.com/portainer/portainer/api/crypto"
|
||||
"github.com/portainer/portainer/api/database"
|
||||
"github.com/portainer/portainer/api/docker"
|
||||
"github.com/portainer/portainer/api/exec"
|
||||
"github.com/portainer/portainer/api/filesystem"
|
||||
|
@ -100,6 +101,10 @@ func initLDAPService() portainer.LDAPService {
|
|||
return &ldap.Service{}
|
||||
}
|
||||
|
||||
func initDatabaseService() portainer.DatabaseService {
|
||||
return &database.Service{}
|
||||
}
|
||||
|
||||
func initGitService() portainer.GitService {
|
||||
return &git.Service{}
|
||||
}
|
||||
|
@ -526,6 +531,8 @@ func main() {
|
|||
|
||||
gitService := initGitService()
|
||||
|
||||
databaseService := initDatabaseService()
|
||||
|
||||
cryptoService := initCryptoService()
|
||||
|
||||
digitalSignatureService := initDigitalSignatureService()
|
||||
|
@ -684,6 +691,7 @@ func main() {
|
|||
ComposeStackManager: composeStackManager,
|
||||
ExtensionManager: extensionManager,
|
||||
CryptoService: cryptoService,
|
||||
DatabaseService: databaseService,
|
||||
JWTService: jwtService,
|
||||
FileService: fileService,
|
||||
LDAPService: ldapService,
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"github.com/boltdb/bolt"
|
||||
//"strconv"
|
||||
//"net/http"
|
||||
//"io/ioutil"
|
||||
)
|
||||
|
||||
const (
|
||||
databaseFileName = "portainer.db"
|
||||
)
|
||||
|
||||
// Service represents a service for managing Database.
|
||||
type Service struct{}
|
||||
|
||||
// DatabaseExport makes the BoltDB into read only mode, takes a backup and then put it back to writable mode.
|
||||
func (service *Service) DatabaseExport(storePath string) (int64, error) {
|
||||
//var databaseExport int64
|
||||
//var w http.ResponseWriter
|
||||
// var r io.Reader
|
||||
dataStorePath := storePath + "/" + databaseFileName
|
||||
|
||||
_, err := bolt.Open(dataStorePath, 0666, &bolt.Options{ReadOnly: true})
|
||||
|
||||
/*
|
||||
db, err := bolt.Open(dataStorePath, 0666, &bolt.Options{ReadOnly: true})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
err := db.View(func(tx *bolt.Tx) error {
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
w.Header().Set("Content-Disposition", `attachment; filename="portainer.db"`)
|
||||
w.Header().Set("Content-Length", strconv.Itoa(int(tx.Size())))
|
||||
databaseExport, err := tx.WriteTo(w)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
*/
|
||||
return 0, err
|
||||
}
|
|
@ -84,6 +84,11 @@ func (service *Service) GetBinaryFolder() string {
|
|||
return path.Join(service.fileStorePath, BinaryStorePath)
|
||||
}
|
||||
|
||||
// GetRootFolder returns the full path to the root store on the filesystem
|
||||
func (service *Service) GetRootFolder() string {
|
||||
return service.fileStorePath
|
||||
}
|
||||
|
||||
// ExtractExtensionArchive extracts the content of an extension archive
|
||||
// specified as raw data into the binary store on the filesystem
|
||||
func (service *Service) ExtractExtensionArchive(data []byte) error {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
//"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
"github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
func (handler *Handler) databaseExport(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
storePath := handler.FileService.GetRootFolder()
|
||||
databaseExport, err := handler.DatabaseService.DatabaseExport(storePath)
|
||||
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Error exporting database", err}
|
||||
}
|
||||
|
||||
database := &portainer.Database{
|
||||
DatabaseExport: databaseExport,
|
||||
}
|
||||
|
||||
//w.Header().Set("Content-Type", "application/octet-stream")
|
||||
//w.Header().Set("Content-Disposition", `attachment; filename="my.db"`)
|
||||
//w.Header().Set("Content-Length", strconv.Itoa(int(tx.Size())))
|
||||
|
||||
return response.JSON(w, database)
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
)
|
||||
|
||||
// Handler is the HTTP handler used to handle webhook operations.
|
||||
type Handler struct {
|
||||
*mux.Router
|
||||
DatabaseService portainer.DatabaseService
|
||||
FileService portainer.FileService
|
||||
}
|
||||
|
||||
// NewHandler creates a handler to manage settings operations.
|
||||
func NewHandler(bouncer *security.RequestBouncer) *Handler {
|
||||
h := &Handler{
|
||||
Router: mux.NewRouter(),
|
||||
}
|
||||
h.Handle("/database",
|
||||
//bouncer.RestrictedAccess(httperror.LoggerHandler(h.databaseExport))).Methods(http.MethodGet)
|
||||
bouncer.PublicAccess(httperror.LoggerHandler(h.databaseExport))).Methods(http.MethodGet)
|
||||
return h
|
||||
}
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/portainer/portainer/api/http/handler/roles"
|
||||
|
||||
"github.com/portainer/portainer/api/http/handler/auth"
|
||||
"github.com/portainer/portainer/api/http/handler/database"
|
||||
"github.com/portainer/portainer/api/http/handler/dockerhub"
|
||||
"github.com/portainer/portainer/api/http/handler/endpointgroups"
|
||||
"github.com/portainer/portainer/api/http/handler/endpointproxy"
|
||||
|
@ -34,6 +35,7 @@ import (
|
|||
// Handler is a collection of all the service handlers.
|
||||
type Handler struct {
|
||||
AuthHandler *auth.Handler
|
||||
DatabaseHandler *database.Handler
|
||||
DockerHubHandler *dockerhub.Handler
|
||||
EndpointGroupHandler *endpointgroups.Handler
|
||||
EndpointHandler *endpoints.Handler
|
||||
|
@ -63,6 +65,8 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
switch {
|
||||
case strings.HasPrefix(r.URL.Path, "/api/auth"):
|
||||
http.StripPrefix("/api", h.AuthHandler).ServeHTTP(w, r)
|
||||
case strings.HasPrefix(r.URL.Path, "/api/database"):
|
||||
http.StripPrefix("/api", h.DatabaseHandler).ServeHTTP(w, r)
|
||||
case strings.HasPrefix(r.URL.Path, "/api/dockerhub"):
|
||||
http.StripPrefix("/api", h.DockerHubHandler).ServeHTTP(w, r)
|
||||
case strings.HasPrefix(r.URL.Path, "/api/endpoint_groups"):
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/portainer/portainer/api/docker"
|
||||
"github.com/portainer/portainer/api/http/handler"
|
||||
"github.com/portainer/portainer/api/http/handler/auth"
|
||||
"github.com/portainer/portainer/api/http/handler/database"
|
||||
"github.com/portainer/portainer/api/http/handler/dockerhub"
|
||||
"github.com/portainer/portainer/api/http/handler/endpointgroups"
|
||||
"github.com/portainer/portainer/api/http/handler/endpointproxy"
|
||||
|
@ -51,6 +52,7 @@ type Server struct {
|
|||
JobScheduler portainer.JobScheduler
|
||||
Snapshotter portainer.Snapshotter
|
||||
RoleService portainer.RoleService
|
||||
DatabaseService portainer.DatabaseService
|
||||
DockerHubService portainer.DockerHubService
|
||||
EndpointService portainer.EndpointService
|
||||
EndpointGroupService portainer.EndpointGroupService
|
||||
|
@ -122,6 +124,10 @@ func (server *Server) Start() error {
|
|||
var roleHandler = roles.NewHandler(requestBouncer)
|
||||
roleHandler.RoleService = server.RoleService
|
||||
|
||||
var databaseHandler = database.NewHandler(requestBouncer)
|
||||
databaseHandler.DatabaseService = server.DatabaseService
|
||||
databaseHandler.FileService = server.FileService
|
||||
|
||||
var dockerHubHandler = dockerhub.NewHandler(requestBouncer)
|
||||
dockerHubHandler.DockerHubService = server.DockerHubService
|
||||
|
||||
|
@ -225,6 +231,7 @@ func (server *Server) Start() error {
|
|||
server.Handler = &handler.Handler{
|
||||
RoleHandler: roleHandler,
|
||||
AuthHandler: authHandler,
|
||||
DatabaseHandler: databaseHandler,
|
||||
DockerHubHandler: dockerHubHandler,
|
||||
EndpointGroupHandler: endpointGroupHandler,
|
||||
EndpointHandler: endpointHandler,
|
||||
|
|
|
@ -224,6 +224,11 @@ type (
|
|||
Password string `json:"Password,omitempty"`
|
||||
}
|
||||
|
||||
// Database represents all the required information to connect and use the database features
|
||||
Database struct {
|
||||
DatabaseExport int64 `json:"DatabaseExport"`
|
||||
}
|
||||
|
||||
// EndpointID represents an endpoint identifier
|
||||
EndpointID int
|
||||
|
||||
|
@ -575,6 +580,11 @@ type (
|
|||
Valid bool `json:"Valid,omitempty"`
|
||||
}
|
||||
|
||||
// Server defines the interface to serve the API
|
||||
DatabaseService interface {
|
||||
DatabaseExport(storePath string) (int64, error)
|
||||
}
|
||||
|
||||
// CLIService represents a service for managing CLI
|
||||
CLIService interface {
|
||||
ParseFlags(version string) (*CLIFlags, error)
|
||||
|
@ -789,6 +799,7 @@ type (
|
|||
GetScheduleFolder(identifier string) string
|
||||
ExtractExtensionArchive(data []byte) error
|
||||
GetBinaryFolder() string
|
||||
GetRootFolder() string
|
||||
}
|
||||
|
||||
// GitService represents a service for managing Git
|
||||
|
|
Loading…
Reference in New Issue