2017-06-29 10:24:18 +00:00
|
|
|
package control
|
|
|
|
|
2017-07-06 18:51:09 +00:00
|
|
|
import (
|
|
|
|
"encoding/json"
|
2017-07-30 18:05:06 +00:00
|
|
|
"errors"
|
2017-07-06 18:51:09 +00:00
|
|
|
"io/ioutil"
|
2017-07-30 18:05:06 +00:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
log "github.com/sirupsen/logrus"
|
2017-07-06 18:51:09 +00:00
|
|
|
)
|
|
|
|
|
2017-07-30 18:05:06 +00:00
|
|
|
// Server is a Server
|
|
|
|
type Server interface {
|
|
|
|
Start() error
|
|
|
|
Stop() error
|
|
|
|
Exec(command string) error
|
|
|
|
Rebuild() error
|
2017-07-30 18:25:42 +00:00
|
|
|
|
|
|
|
HasPermission(string, string) bool
|
2017-07-30 18:05:06 +00:00
|
|
|
}
|
|
|
|
|
2017-06-29 10:24:18 +00:00
|
|
|
// Server is a single instance of a Service managed by the panel
|
2017-07-30 18:05:06 +00:00
|
|
|
type server struct {
|
2017-07-06 18:51:09 +00:00
|
|
|
// UUID is the unique identifier of the server
|
|
|
|
UUID string `json:"uuid"`
|
|
|
|
|
|
|
|
// ServiceName is the name of the service. It is mainly used to allow storing the service
|
|
|
|
// in the config
|
|
|
|
ServiceName string `json:"serviceName"`
|
2017-07-30 18:05:06 +00:00
|
|
|
service *service
|
|
|
|
environment Environment
|
|
|
|
|
|
|
|
// StartupCommand is the command executed in the environment to start the server
|
|
|
|
StartupCommand string `json:"startupCommand"`
|
|
|
|
|
|
|
|
// DockerContainer holds information regarding the docker container when the server
|
|
|
|
// is running in a docker environment
|
|
|
|
DockerContainer dockerContainer `json:"dockerContainer"`
|
2017-07-06 18:51:09 +00:00
|
|
|
|
2017-07-30 18:05:06 +00:00
|
|
|
// EnvironmentVariables are set in the Environment the server is running in
|
|
|
|
EnvironmentVariables map[string]string `json:"env"`
|
|
|
|
|
|
|
|
// Allocations contains the ports and ip addresses assigned to the server
|
|
|
|
Allocations allocations `json:"allocation"`
|
|
|
|
|
|
|
|
// Settings are the environment settings and limitations for the server
|
|
|
|
Settings settings `json:"settings"`
|
|
|
|
|
|
|
|
// Keys are some auth keys we will hopefully replace by something better.
|
2017-07-06 18:51:09 +00:00
|
|
|
Keys map[string][]string `json:"keys"`
|
|
|
|
}
|
|
|
|
|
2017-07-30 18:05:06 +00:00
|
|
|
type allocations struct {
|
|
|
|
Ports []int16 `json:"ports"`
|
|
|
|
MainIP string `json:"ip"`
|
|
|
|
MainPort int16 `json:"port"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type settings struct {
|
|
|
|
Memory int64 `json:"memory"`
|
|
|
|
Swap int64 `json:"swap"`
|
|
|
|
IO int64 `json:"io"`
|
|
|
|
CPU int16 `json:"cpu"`
|
|
|
|
Disk int64 `json:"disk"`
|
|
|
|
Image string `json:"image"`
|
|
|
|
User string `json:"user"`
|
|
|
|
UserID int16 `json:"userID"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type dockerContainer struct {
|
|
|
|
ID string `json:"id"`
|
|
|
|
Image string `json:"image"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// ensure server implements Server
|
|
|
|
var _ Server = &server{}
|
|
|
|
|
|
|
|
var servers map[string]*server
|
2017-07-06 18:51:09 +00:00
|
|
|
|
|
|
|
// LoadServerConfigurations loads the configured servers from a specified path
|
|
|
|
func LoadServerConfigurations(path string) error {
|
|
|
|
serverFiles, err := ioutil.ReadDir(path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-07-30 18:05:06 +00:00
|
|
|
servers = make(map[string]*server)
|
2017-07-06 18:51:09 +00:00
|
|
|
|
|
|
|
for _, file := range serverFiles {
|
|
|
|
if !file.IsDir() {
|
|
|
|
server, err := loadServerConfiguration(path + file.Name())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
servers[server.UUID] = server
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-07-30 18:05:06 +00:00
|
|
|
func loadServerConfiguration(path string) (*server, error) {
|
2017-07-06 18:51:09 +00:00
|
|
|
file, err := ioutil.ReadFile(path)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2017-07-30 18:05:06 +00:00
|
|
|
server := &server{}
|
2017-07-06 18:51:09 +00:00
|
|
|
if err := json.Unmarshal(file, server); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return server, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetServer returns the server identified by the provided uuid
|
2017-07-30 18:05:06 +00:00
|
|
|
func GetServer(uuid string) Server {
|
2017-08-02 19:35:15 +00:00
|
|
|
server := servers[uuid]
|
|
|
|
if server == nil {
|
|
|
|
return nil // https://golang.org/doc/faq#nil_error
|
|
|
|
}
|
|
|
|
return server
|
2017-07-06 18:51:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewServer creates a new Server
|
2017-07-30 18:05:06 +00:00
|
|
|
func NewServer() Server {
|
|
|
|
return new(server)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *server) Start() error {
|
|
|
|
/*if err := s.Environment().Create(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := s.Environment().Start(); err != nil {
|
|
|
|
return err
|
|
|
|
}*/
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *server) Stop() error {
|
|
|
|
/*if err := s.Environment().Stop(); err != nil {
|
|
|
|
return err
|
|
|
|
}*/
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *server) Exec(command string) error {
|
|
|
|
/*if err := s.Environment().Exec(command); err != nil {
|
|
|
|
return err
|
|
|
|
}*/
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *server) Rebuild() error {
|
|
|
|
/*if err := s.Environment().ReCreate(); err != nil {
|
|
|
|
return err
|
|
|
|
}*/
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Service returns the server's service configuration
|
|
|
|
func (s *server) Service() *service {
|
|
|
|
if s.service == nil {
|
|
|
|
// TODO: Properly use the correct service, mock for now.
|
|
|
|
s.service = &service{
|
|
|
|
DockerImage: "quay.io/pterodactyl/core:java",
|
|
|
|
EnvironmentName: "docker",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return s.service
|
|
|
|
}
|
|
|
|
|
|
|
|
// UUIDShort returns the first block of the UUID
|
|
|
|
func (s *server) UUIDShort() string {
|
|
|
|
return s.UUID[0:strings.Index(s.UUID, "-")]
|
|
|
|
}
|
|
|
|
|
|
|
|
// Environment returns the servers environment
|
|
|
|
func (s *server) Environment() (Environment, error) {
|
|
|
|
var err error
|
|
|
|
if s.environment == nil {
|
|
|
|
switch s.Service().EnvironmentName {
|
|
|
|
case "docker":
|
|
|
|
s.environment, err = NewDockerEnvironment(s)
|
|
|
|
default:
|
|
|
|
log.WithField("service", s.ServiceName).Error("Invalid environment name")
|
|
|
|
return nil, errors.New("Invalid environment name")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return s.environment, err
|
2017-06-29 10:24:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// HasPermission checks wether a provided token has a specific permission
|
2017-07-30 18:05:06 +00:00
|
|
|
func (s *server) HasPermission(token string, permission string) bool {
|
2017-07-06 18:51:09 +00:00
|
|
|
for key, perms := range s.Keys {
|
|
|
|
if key == token {
|
|
|
|
for _, perm := range perms {
|
|
|
|
if perm == permission || perm == "s:*" {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
2017-06-29 10:24:18 +00:00
|
|
|
}
|