added more stuff including some of docker support

This commit is contained in:
ACoolName 2025-03-15 21:16:17 +02:00
parent 4b9c30be7e
commit 5f99ec77a0
22 changed files with 1009 additions and 261 deletions

View File

@ -1,156 +0,0 @@
package mongo
import (
"context"
"git.acooldomain.co/server-manager/backend-kubernetes-go/dbhandler"
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type ServerPermissions struct {
Username string `json:"username"`
ServerId string `json:"server_id"`
Permissions models.Permission `json:"permissions"`
}
type MongoDbAuthorizationHandler struct {
dbhandler.AuthorizationDbHandler
collection *mongo.Collection
}
func (self *MongoDbAuthorizationHandler) RemoveUser(username string) error {
_, err := self.collection.DeleteMany(
context.Background(),
bson.D{
{Key: "username", Value: username},
},
)
return err
}
func (self *MongoDbAuthorizationHandler) RemoveServer(serverId string) error {
_, err := self.collection.DeleteMany(
context.Background(),
bson.D{
{Key: "server_id", Value: serverId},
},
)
return err
}
func (self *MongoDbAuthorizationHandler) AddPermissions(username string, serverId string, permissions models.Permission) error {
var serverPermissions ServerPermissions
err := self.collection.FindOne(
context.Background(),
bson.D{
{Key: "username", Value: username},
{Key: "server_id", Value: serverId},
},
).Decode(&serverPermissions)
if err != nil {
return err
}
newPermissions := serverPermissions.Permissions | permissions
_, err = self.collection.UpdateOne(
context.Background(),
bson.D{
{Key: "username", Value: username},
{Key: "server_id", Value: serverId},
},
bson.M{"$set": bson.M{
"permissions": newPermissions,
},
},
)
return err
}
func (self *MongoDbAuthorizationHandler) RemovePermissions(username string, serverId string, permissions models.Permission) error {
var serverPermissions ServerPermissions
err := self.collection.FindOne(
context.Background(),
bson.D{
{Key: "username", Value: username},
{Key: "server_id", Value: serverId},
},
).Decode(&serverPermissions)
if err != nil {
return err
}
newPermissions := serverPermissions.Permissions | permissions ^ permissions
_, err = self.collection.UpdateOne(
context.Background(),
bson.D{
{Key: "username", Value: username},
{Key: "server_id", Value: serverId},
},
bson.M{"$set": bson.M{
"permissions": newPermissions,
},
},
)
return err
}
func (self *MongoDbAuthorizationHandler) SetPermissions(username string, serverId string, permissions models.Permission) error {
_, err := self.collection.UpdateOne(
context.Background(),
bson.D{
{Key: "username", Value: username},
{Key: "server_id", Value: serverId},
},
bson.M{"$set": bson.M{
"permissions": permissions,
},
},
)
return err
}
func (self *MongoDbAuthorizationHandler) GetPermissions(username string, serverId string) (models.Permission, error) {
var serverPermissions ServerPermissions
err := self.collection.FindOne(
context.Background(),
bson.D{
{Key: "username", Value: username},
{Key: "server_id", Value: serverId},
},
).Decode(&serverPermissions)
if err != nil {
return 0, err
}
return serverPermissions.Permissions, nil
}
func NewAuthorizationHandler(config models.MongoDBConfig) (*MongoDbAuthorizationHandler, error) {
clientOptions := options.Client().ApplyURI(config.Url).SetAuth(options.Credential{
Username: config.Username,
Password: config.Password,
})
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
return nil, err
}
return &MongoDbAuthorizationHandler{
collection: client.Database(config.Database).Collection(config.Collection),
}, nil
}

192
db_handler/mongo/servers.go Normal file
View File

@ -0,0 +1,192 @@
package mongo
import (
"context"
"fmt"
"time"
"git.acooldomain.co/server-manager/backend-kubernetes-go/dbhandler"
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type Image struct {
Registry string `bson:"registry"`
Tag string `bson:"tag"`
}
type Port struct {
PublicPort uint16 `bson:"public_port"`
ContainerPort uint16 `bson:"container_port"`
Protocol models.PortProtocol `bson:"protocol"`
}
type Server struct {
Id string `bson:"id"`
Owner string `bson:"owner"`
Image Image `bson:"image"`
Nickname string `bson:"nickname"`
Command string `bson:"command"`
Ports []Port `bson:"ports"`
}
func convertToDbServer(server dbhandler.Server) Server {
ports := make([]Port, len(server.Ports))
for i, port := range server.Ports {
ports[i] = Port{
PublicPort: port.PublicPort,
ContainerPort: port.ContainerPort,
Protocol: port.Protocol,
}
}
return Server{
Id: server.Id,
Owner: server.Owner,
Image: Image{
Registry: server.Image.Registry,
Tag: server.Image.Tag,
},
Nickname: server.Nickname,
Command: server.Command,
Ports: ports,
}
}
func convertToResponseServer(server Server) dbhandler.Server {
ports := make([]models.Port, len(server.Ports))
for i, port := range server.Ports {
ports[i] = models.Port{
PublicPort: port.PublicPort,
ContainerPort: port.ContainerPort,
Protocol: port.Protocol,
}
}
return dbhandler.Server{
Id: server.Id,
Owner: server.Owner,
Image: &models.Image{
Registry: server.Image.Registry,
Tag: server.Image.Tag,
},
Nickname: server.Nickname,
Command: server.Command,
Ports: ports,
}
}
type ServersDbHandler struct {
dbhandler.ServersDbHandler
collection *mongo.Collection
}
func (self *ServersDbHandler) ListServers(ctx context.Context) ([]dbhandler.Server, error) {
var servers []Server
cursor, err := self.collection.Find(ctx, bson.M{})
if err != nil {
return nil, err
}
defer cursor.Close(ctx)
err = cursor.All(ctx, &servers)
if err != nil {
return nil, err
}
dbServers := make([]dbhandler.Server, len(servers))
for i, server := range servers {
dbServers[i] = convertToResponseServer(server)
}
return dbServers, nil
}
func (self *ServersDbHandler) GetServer(ctx context.Context, serverId string) (*dbhandler.Server, error) {
var server Server
err := self.collection.FindOne(ctx, bson.M{"server_id": serverId}).Decode(&server)
if err != nil {
return nil, err
}
responseServer := convertToResponseServer(server)
return &responseServer, nil
}
func (self *ServersDbHandler) CreateServer(ctx context.Context, server dbhandler.Server) error {
dbServer := convertToDbServer(server)
_, err := self.collection.InsertOne(ctx, &dbServer)
return err
}
func (self *ServersDbHandler) DeleteServer(ctx context.Context, serverId string) error {
_, err := self.collection.DeleteOne(ctx, bson.M{
"server_id": serverId,
})
return err
}
func (self *ServersDbHandler) UpdateServer(ctx context.Context, serverId string, updateParams dbhandler.ServerUpdateRequest) error {
updateServerRequest := bson.M{}
if updateParams.Owner != "" {
updateServerRequest["owner"] = updateParams.Owner
}
if updateParams.Image != nil {
updateServerRequest["image"] = bson.M{
"registry": updateParams.Image.Registry,
"tag": updateParams.Image.Tag,
}
}
if updateParams.Ports != nil {
ports := make([]bson.M, len(updateParams.Ports))
for i, port := range updateParams.Ports {
ports[i] = bson.M{
"number": port.PublicPort,
"protocol": port.Protocol,
}
}
}
if updateParams.Nickname != "" {
updateServerRequest["nickname"] = updateParams.Nickname
}
if updateParams.Command != "" {
updateServerRequest["command"] = updateParams.Command
}
_, err := self.collection.UpdateOne(ctx, bson.M{"server_id": serverId}, bson.M{"$set": updateServerRequest})
return err
}
func NewServersDbHandler(config models.MongoDBConfig) (*ServersDbHandler, error) {
clientOptions := options.Client().ApplyURI(config.Url).SetAuth(options.Credential{
Username: config.Username,
Password: config.Password,
})
ctx, cancel := context.WithTimeoutCause(context.Background(), 30*time.Second, fmt.Errorf("Timeout"))
defer cancel()
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
return nil, err
}
return &ServersDbHandler{
collection: client.Database(config.Database).Collection(config.Collection),
}, nil
}

View File

@ -0,0 +1,161 @@
package mongo
import (
"context"
"fmt"
"time"
"git.acooldomain.co/server-manager/backend-kubernetes-go/dbhandler"
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type ServerPermissions struct {
Username string `bson:"username"`
ServerId string `bson:"server_id"`
Permissions models.Permission `bson:"permissions"`
}
type AuthorizationDbHandler struct {
dbhandler.ServersAuthorizationDbHandler
collection *mongo.Collection
}
func (self *AuthorizationDbHandler) RemoveUser(ctx context.Context, username string) error {
_, err := self.collection.DeleteMany(
ctx,
bson.M{
"username": username,
},
)
return err
}
func (self *AuthorizationDbHandler) RemoveServer(ctx context.Context, serverId string) error {
_, err := self.collection.DeleteMany(
ctx,
bson.M{
"server_id": serverId,
},
)
return err
}
func (self *AuthorizationDbHandler) AddPermissions(ctx context.Context, username string, serverId string, permissions models.Permission) error {
var serverPermissions ServerPermissions
err := self.collection.FindOne(
ctx,
bson.M{
"username": username,
"server_id": serverId,
},
).Decode(&serverPermissions)
if err != nil {
return err
}
newPermissions := serverPermissions.Permissions | permissions
_, err = self.collection.UpdateOne(
ctx,
bson.M{
"username": username,
"server_id": serverId,
},
bson.M{"$set": bson.M{
"permissions": newPermissions,
},
},
)
return err
}
func (self *AuthorizationDbHandler) RemovePermissions(ctx context.Context, username string, serverId string, permissions models.Permission) error {
var serverPermissions ServerPermissions
err := self.collection.FindOne(
ctx,
bson.M{
"username": username,
"server_id": serverId,
},
).Decode(&serverPermissions)
if err != nil {
return err
}
newPermissions := serverPermissions.Permissions | permissions ^ permissions
_, err = self.collection.UpdateOne(
ctx,
bson.M{
"username": username,
"server_id": serverId,
},
bson.M{"$set": bson.M{
"permissions": newPermissions,
},
},
)
return err
}
func (self *AuthorizationDbHandler) SetPermissions(ctx context.Context, username string, serverId string, permissions models.Permission) error {
_, err := self.collection.UpdateOne(
ctx,
bson.M{
"username": username,
"server_id": serverId,
},
bson.M{"$set": bson.M{
"permissions": permissions,
},
},
)
return err
}
func (self *AuthorizationDbHandler) GetPermissions(ctx context.Context, username string, serverId string) (models.Permission, error) {
var serverPermissions ServerPermissions
err := self.collection.FindOne(
ctx,
bson.M{
"username": username,
"server_id": serverId,
},
).Decode(&serverPermissions)
if err != nil {
return 0, err
}
return serverPermissions.Permissions, nil
}
func NewAuthorizationHandler(config models.MongoDBConfig) (*AuthorizationDbHandler, error) {
clientOptions := options.Client().ApplyURI(config.Url).SetAuth(options.Credential{
Username: config.Username,
Password: config.Password,
})
ctx, cancel := context.WithTimeoutCause(context.Background(), 30*time.Second, fmt.Errorf("Timeout"))
defer cancel()
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
return nil, err
}
return &AuthorizationDbHandler{
collection: client.Database(config.Database).Collection(config.Collection),
}, nil
}

View File

@ -3,6 +3,7 @@ package mongo
import (
"context"
"fmt"
"time"
"git.acooldomain.co/server-manager/backend-kubernetes-go/dbhandler"
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
@ -23,14 +24,14 @@ type Invite struct {
Token string `json:"token"`
}
type MongoDbUserPassHandler struct {
type UserPassAuthenticationDbHandler struct {
dbhandler.UserPassAuthanticationDbHandler
collection *mongo.Collection
}
func (self *MongoDbUserPassHandler) AuthenticateUser(username string, password string) (models.Permission, error) {
func (self *UserPassAuthenticationDbHandler) AuthenticateUser(ctx context.Context, username string, password string) (models.Permission, error) {
var user AuthUser
err := self.collection.FindOne(context.Background(), bson.D{bson.E{Key: "username", Value: username}}).Decode(&user)
err := self.collection.FindOne(ctx, bson.M{"username": username}).Decode(&user)
if err != nil {
return 0, err
@ -49,7 +50,8 @@ func (self *MongoDbUserPassHandler) AuthenticateUser(username string, password s
return user.Permissions, nil
}
func (self *MongoDbUserPassHandler) CreateUser(
func (self *UserPassAuthenticationDbHandler) CreateUser(
ctx context.Context,
username string,
password string,
permissions models.Permission,
@ -60,7 +62,7 @@ func (self *MongoDbUserPassHandler) CreateUser(
return err
}
_, err = self.collection.InsertOne(context.Background(), &AuthUser{
_, err = self.collection.InsertOne(ctx, &AuthUser{
Username: username,
HashedPassword: hashedPassword,
Permissions: permissions,
@ -69,25 +71,26 @@ func (self *MongoDbUserPassHandler) CreateUser(
return err
}
func (self *MongoDbUserPassHandler) RemoveUser(username string) error {
func (self *UserPassAuthenticationDbHandler) RemoveUser(ctx context.Context, username string) error {
_, err := self.collection.DeleteOne(
context.Background(),
bson.D{
{Key: "username", Value: username},
ctx,
bson.M{
"username": username,
},
)
return err
}
func (self *MongoDbUserPassHandler) SetPermissions(
func (self *UserPassAuthenticationDbHandler) SetPermissions(
ctx context.Context,
username string,
permissions models.Permission,
) error {
_, err := self.collection.UpdateOne(
context.Background(),
bson.D{
{Key: "username", Value: username},
ctx,
bson.M{
"username": username,
},
bson.M{
"$set": bson.M{
@ -99,19 +102,22 @@ func (self *MongoDbUserPassHandler) SetPermissions(
return err
}
func NewUserPassAuthHandler(config models.MongoDBConfig) (*MongoDbUserPassHandler, error) {
func NewUserPassAuthHandler(config models.MongoDBConfig) (*UserPassAuthenticationDbHandler, error) {
clientOptions := options.Client().ApplyURI(config.Url).SetAuth(options.Credential{
Username: config.Username,
Password: config.Password,
})
client, err := mongo.Connect(context.TODO(), clientOptions)
ctx, cancel := context.WithTimeoutCause(context.Background(), 30*time.Second, fmt.Errorf("Timeout"))
defer cancel()
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
return nil, err
}
return &MongoDbUserPassHandler{
return &UserPassAuthenticationDbHandler{
collection: client.Database(config.Database).Collection(config.Collection),
}, nil
}

View File

@ -2,6 +2,8 @@ package mongo
import (
"context"
"fmt"
"time"
"git.acooldomain.co/server-manager/backend-kubernetes-go/dbhandler"
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
@ -10,44 +12,60 @@ import (
"go.mongodb.org/mongo-driver/mongo/options"
)
type MongoDbUserHandler struct {
type User struct {
Username string `bson:"username"`
Email string `bson:"email"`
Nickname string `bson:"nickname"`
}
type UsersDbHandler struct {
dbhandler.UsersDBHandler
collection *mongo.Collection
}
func (self *MongoDbUserHandler) GetUser(username string) (*dbhandler.User, error) {
users, err := self.collection.Find(context.TODO(), bson.D{bson.E{Key: "username", Value: username}})
func (self *UsersDbHandler) GetUser(ctx context.Context, username string) (*dbhandler.User, error) {
var user User
err := self.collection.FindOne(ctx, bson.M{"username": username}).Decode(&user)
if err != nil {
return nil, err
}
var user dbhandler.User
err = users.Decode(&user)
if err != nil {
return nil, err
}
return &user, nil
return &dbhandler.User{
Username: user.Username,
Email: user.Email,
Nickname: user.Nickname,
}, nil
}
func (self *MongoDbUserHandler) ListUsers() ([]dbhandler.User, error) {
users, err := self.collection.Find(context.TODO(), bson.D{})
func (self *UsersDbHandler) ListUsers(ctx context.Context) ([]dbhandler.User, error) {
cursor, err := self.collection.Find(ctx, bson.M{})
if err != nil {
return nil, err
}
defer cursor.Close(ctx)
var response []dbhandler.User
users.All(nil, &response)
var users []User
cursor.All(nil, &users)
response := make([]dbhandler.User, len(users))
for i, user := range users {
response[i] = dbhandler.User{
Username: user.Username,
Nickname: user.Nickname,
Email: user.Email,
}
}
return response, nil
}
func (self *MongoDbUserHandler) CreateUser(user dbhandler.User) error {
_, err := self.collection.InsertOne(context.TODO(), &dbhandler.User{
func (self *UsersDbHandler) CreateUser(ctx context.Context, user dbhandler.User) error {
_, err := self.collection.InsertOne(ctx, &User{
Username: user.Username,
Email: user.Email,
Nickname: user.Nickname,
@ -60,19 +78,28 @@ func (self *MongoDbUserHandler) CreateUser(user dbhandler.User) error {
return nil
}
func NewUsersHandler(config models.MongoDBConfig) (*MongoDbUserHandler, error) {
func (self *UsersDbHandler) DeleteUser(ctx context.Context, username string) error {
_, err := self.collection.DeleteOne(ctx, bson.M{"username": username})
return err
}
func NewUsersHandler(config models.MongoDBConfig) (*UsersDbHandler, error) {
clientOptions := options.Client().ApplyURI(config.Url).SetAuth(options.Credential{
Username: config.Username,
Password: config.Password,
})
client, err := mongo.Connect(context.TODO(), clientOptions)
ctx, cancel := context.WithTimeoutCause(context.Background(), 30*time.Second, fmt.Errorf("Timeout"))
defer cancel()
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
return nil, err
}
return &MongoDbUserHandler{
return &UsersDbHandler{
collection: client.Database(config.Database).Collection(config.Collection),
}, nil
}

View File

@ -1,23 +1,22 @@
package dbhandler
type Image struct {
Registry string
Tag string
}
import "git.acooldomain.co/server-manager/backend-kubernetes-go/models"
type Server struct {
Id string
Owner string
Image string
Image *models.Image
Nickname string
Command string
Ports []models.Port
}
type ServerUpdateRequest struct {
Owner string
Image string
Image *models.Image
Nickname string
Command string
Ports []models.Port
}
type ServersDbHandler interface {

View File

@ -2,7 +2,7 @@ package dbhandler
import "git.acooldomain.co/server-manager/backend-kubernetes-go/models"
type AuthorizationDbHandler interface {
type ServersAuthorizationDbHandler interface {
AddPermissions(username string, server_id string, permissions models.Permission) error
RemovePermissions(username string, server_id string, permissions models.Permission) error
SetPermissions(username string, server_id string, permissions models.Permission) error

View File

@ -1,9 +1,9 @@
package dbhandler
type User struct {
Username string `json:"username"`
Nickname string `json:"nickname"`
Email string `json:"email"`
Username string
Nickname string
Email string
}
type UsersDBHandler interface {

View File

@ -7,6 +7,9 @@ use (
./db_handler/mongo
./mail
./models
./instance_manager
./instance_manager/docker
./instance_manager/kubernetes
./servers
./users
)

View File

@ -3,27 +3,51 @@ github.com/buildkite/shellwords v0.0.0-20180315110454-59467a9b8e10/go.mod h1:gv0
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

View File

@ -0,0 +1,3 @@
module git.acooldomain.co/server-manager/backend-kubernetes-go/instance_manager/docker
go 1.22.0

View File

@ -0,0 +1,317 @@
package docker
import (
"context"
"encoding/json"
"fmt"
"log"
"net"
"reflect"
"strings"
instancemanager "git.acooldomain.co/server-manager/backend-kubernetes-go/instance_manager"
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/volume"
"github.com/docker/docker/client"
)
type InstanceManager struct {
instancemanager.InstanceManager
client client.Client
}
func flattenMap(m map[string]any, previous ...string) map[string]string {
var flattenedMap map[string]string
for key, value := range m {
v := reflect.ValueOf(value)
switch v.Kind() {
case reflect.Map:
inner := flattenMap(v.Interface().(map[string]any), append(previous, key)...)
for key, value := range inner {
flattenedMap[key] = value
}
default:
flattenedMap[key] = fmt.Sprintf("%v", value)
}
}
return flattenedMap
}
func convertLabelsToFilter(labels any) (*filters.Args, error) {
args := filters.NewArgs()
raw, err := json.Marshal(labels)
if err != nil {
return nil, err
}
var unflattenedMap map[string]any
err = json.Unmarshal(raw, &unflattenedMap)
if err != nil {
return nil, err
}
flatMap := flattenMap(unflattenedMap)
for key, value := range flatMap {
args.Add(key, value)
}
return &args, nil
}
func convertContainerPortsToPorts(ports []types.Port) []models.Port {
containerPorts := make([]models.Port, len(ports))
logger := log.Default()
for i, port := range ports {
var portProtocol models.PortProtocol
switch port.Type {
case "TCP":
portProtocol = models.TCP
case "UDP":
portProtocol = models.UDP
default:
logger.Println(fmt.Sprintf("Unkown Port Protocol %s assuming TCP", port.Type))
portProtocol = models.TCP
}
containerPorts[i] = models.Port{
PublicPort: port.PublicPort,
ContainerPort: port.PrivatePort,
Protocol: portProtocol,
}
}
return containerPorts
}
func convertContainerImageToImage(image string) models.Image {
imageSegments := strings.Split(image, ":")
imageRegistry := imageSegments[0]
imageTag := imageSegments[1]
return models.Image{
Registry: imageRegistry,
Tag: imageTag,
}
}
func convertImagePortsToPorts(types.Port) *models.Port {
return nil
}
// General
// Read Only
func (self *InstanceManager) ListImages(ctx context.Context) (*instancemanager.Image, error) {
imageFilters, err := convertLabelsToFilter(ImageLabels{Type: Game})
if err != nil {
return nil, err
}
rawImages, err := self.client.ImageList(ctx, image.ListOptions{
Filters: *imageFilters,
})
images := make([]instancemanager.Image, len(rawImages))
for i, rawImage := range rawImages {
imageInspect, _, err := self.client.ImageInspectWithRaw(ctx, rawImage.ID)
if err != nil {
return nil, err
}
}
return nil, nil
}
func (self *InstanceManager) GetServer(ctx context.Context, serverId string) (*instancemanager.Server, error) {
volume, err := self.client.VolumeInspect(ctx, serverId)
if err != nil {
return nil, err
}
var labels VolumeLabels
rawLabels, err := json.Marshal(volume.Labels)
if err != nil {
return nil, err
}
err = json.Unmarshal(rawLabels, &labels)
if err != nil {
return nil, err
}
if labels.Type != Game {
return nil, fmt.Errorf("Server not found")
}
filterArgs, err := convertLabelsToFilter(ContainerLabels{
VolumeId: volume.Name,
Type: Game,
})
serverContainers, err := self.client.ContainerList(
ctx,
container.ListOptions{
Filters: *filterArgs,
},
)
if err != nil {
return nil, err
}
if len(serverContainers) == 0 {
return &instancemanager.Server{
Id: volume.Name,
Running: false,
RunningCommand: "",
RunningImage: nil,
Ports: nil,
}, nil
}
serverContainer := serverContainers[0]
var containerLabels ContainerLabels
rawContainerLabels, err := json.Marshal(serverContainer.Labels)
if err != nil {
return nil, err
}
if err = json.Unmarshal(rawContainerLabels, &containerLabels); err != nil {
return nil, err
}
running := serverContainer.State == "running"
runningCommand := serverContainer.Command
image := convertContainerImageToImage(serverContainer.Image)
return &instancemanager.Server{
Id: volume.Name,
Running: running,
RunningCommand: runningCommand,
Ports: convertContainerPortsToPorts(serverContainer.Ports),
RunningImage: &image,
}, nil
}
func (self *InstanceManager) ListServers(ctx context.Context) ([]instancemanager.Server, error) {
volumeFilter, err := convertLabelsToFilter(VolumeLabels{Type: Game})
if err != nil {
return nil, err
}
containerFilters, err := convertLabelsToFilter(ContainerLabels{Type: Game})
if err != nil {
return nil, err
}
volumes, err := self.client.VolumeList(ctx, volume.ListOptions{Filters: *volumeFilter})
if err != nil {
return nil, err
}
serverStatus := make(map[string]*instancemanager.Server)
for _, volume := range volumes.Volumes {
serverStatus[volume.Name] = &instancemanager.Server{
Id: volume.Name,
Running: false,
RunningCommand: "",
Ports: nil,
RunningImage: nil,
}
}
containers, err := self.client.ContainerList(ctx, container.ListOptions{Filters: *containerFilters})
for _, container := range containers {
rawLabels, err := json.Marshal(container.Labels)
if err != nil {
return nil, err
}
var containerLabels ContainerLabels
err = json.Unmarshal(rawLabels, &containerLabels)
if err != nil {
return nil, err
}
if container.State != "running" {
continue
}
image := convertContainerImageToImage(container.Image)
serverStatus[containerLabels.VolumeId].Ports = convertContainerPortsToPorts(container.Ports)
serverStatus[containerLabels.VolumeId].Running = true
serverStatus[containerLabels.VolumeId].RunningImage = &image
serverStatus[containerLabels.VolumeId].RunningCommand = container.Command
}
servers := make([]instancemanager.Server, len(serverStatus))
i := 0
for _, value := range serverStatus {
servers[i] = *value
i++
}
return servers, nil
}
// State Changing
func (self *InstanceManager) StartServer(ctx context.Context, serverId string, command string, ports []models.Port) error {
return nil
}
func (self *InstanceManager) StopServer(ctx context.Context, serverId string) error {
return nil
}
func (self *InstanceManager) CreateServer(ctx context.Context, image models.Image) (*instancemanager.Server, error) {
return nil, nil
}
func (self *InstanceManager) DeleteServer(ctx context.Context, serverId string) error {
return nil
}
// Terminal
// Read Only
func (self *InstanceManager) GetLogs(ctx context.Context, serverId string) (string, error) {
return "", nil
}
// Status Changing
func (self *InstanceManager) InteractiveTerminal(ctx context.Context, serverId string) (*net.Conn, error) {
return nil, nil
}
func (self *InstanceManager) RunCommand(ctx context.Context, serverId string, command string) (string, error) {
return "", nil
}
// File Browser
// Read Only
func (self *InstanceManager) GetFileBrowser(ctx context.Context, serverId string) (*models.FileBrowser, error) {
return nil, nil
}
func (self *InstanceManager) ListFileBrowsers(ctx context.Context) ([]models.FileBrowser, error) {
return nil, nil
}
// Status Changing
func (self *InstanceManager) StartFileBrowser(ctx context.Context, serverId string) (*models.FileBrowser, error) {
return nil, nil
}
func (self *InstanceManager) StopFileBrowser(ctx context.Context, serverId string) error {
return nil
}

View File

@ -0,0 +1,25 @@
package docker
type ContainerType string
const (
Game ContainerType = "GAME"
FileBrowser = "FILE_BROWSER"
)
type ContainerLabels struct {
OwnerId string `json:"user_id,omitempty"`
ImageId string `json:"image_id,omitempty"`
VolumeId string `json:"volume_id,omitempty"`
Type ContainerType `json:"type,omitempty"`
}
type VolumeLabels struct {
OwnerId string `json:"user_id,omitempty"`
ImageId string `json:"image_id,omitempty"`
Type ContainerType `json:"type,omitempty"`
}
type ImageLabels struct {
Type ContainerType `json:"type,omitempty"`
}

3
instance_manager/go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.acooldomain.co/server-manager/backend-kubernetes-go/instance_manager
go 1.22.0

View File

@ -0,0 +1,62 @@
package instancemanager
import (
"context"
"net"
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
)
type Server struct {
Id string
Running bool
RunningCommand string
RunningImage *models.Image
Ports []models.Port
}
type Port struct {
Number uint16
Protocol models.PortProtocol
}
type Image struct {
Registry string
Tag string
Command string
Ports []Port
}
type InstanceManager interface {
//General
// Read Only
ListImages(ctx context.Context) (*Image, error)
GetServer(ctx context.Context, serverId string) (*Server, error)
ListServers(ctx context.Context) ([]Server, error)
// State Changing
StartServer(ctx context.Context, serverId string, command string, ports []models.Port) error
StopServer(ctx context.Context, serverId string) error
CreateServer(ctx context.Context, image models.Image) (*Server, error)
DeleteServer(ctx context.Context, serverId string) error
// Terminal
// Read Only
GetLogs(ctx context.Context, serverId string) (string, error)
// Status Changing
InteractiveTerminal(ctx context.Context, serverId string) (*net.Conn, error)
RunCommand(ctx context.Context, serverId string, command string) (string, error)
// File Browser
// Read Only
GetFileBrowser(ctx context.Context, serverId string) (*models.FileBrowser, error)
ListFileBrowsers(ctx context.Context) ([]models.FileBrowser, error)
// Status Changing
StartFileBrowser(ctx context.Context, serverId string) (*models.FileBrowser, error)
StopFileBrowser(ctx context.Context, serverId string) error
}

View File

@ -0,0 +1,3 @@
module git.acooldomain.co/server-manager/backend-kubernetes-go/instance_manager/kubernetes
go 1.22.0

View File

@ -0,0 +1,73 @@
package kubernetes
import (
"context"
"net"
"git.acooldomain.co/server-manager/backend-kubernetes-go/instance_manager"
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
)
type InstanceManager struct {
instancemanager.InstanceManager
}
// General
// Read Only
func (self *InstanceManager) GetServer(ctx context.Context, serverId string) (*instancemanager.Server, error) {
return nil, nil
}
func (self *InstanceManager) ListServers(ctx context.Context) ([]instancemanager.Server, error) {
return nil, nil
}
// State Changing
func (self *InstanceManager) StartServer(ctx context.Context, serverId string, command string, ports []models.Port) error {
return nil
}
func (self *InstanceManager) StopServer(ctx context.Context, serverId string) error {
return nil
}
func (self *InstanceManager) CreateServer(ctx context.Context, image models.Image) (*instancemanager.Server, error) {
return nil, nil
}
func (self *InstanceManager) DeleteServer(ctx context.Context, serverId string) error {
return nil
}
// Terminal
// Read Only
func (self *InstanceManager) GetLogs(ctx context.Context, serverId string) (string, error) {
return "", nil
}
// Status Changing
func (self *InstanceManager) InteractiveTerminal(ctx context.Context, serverId string) (*net.Conn, error) {
return nil, nil
}
func (self *InstanceManager) RunCommand(ctx context.Context, serverId string, command string) (string, error) {
return "", nil
}
// File Browser
// Read Only
func (self *InstanceManager) GetFileBrowser(ctx context.Context, serverId string) (*models.FileBrowser, error) {
return nil, nil
}
func (self *InstanceManager) ListFileBrowsers(ctx context.Context) ([]models.FileBrowser, error) {
return nil, nil
}
// Status Changing
func (self *InstanceManager) StartFileBrowser(ctx context.Context, serverId string) (*models.FileBrowser, error) {
return nil, nil
}
func (self *InstanceManager) StopFileBrowser(ctx context.Context, serverId string) error {
return nil
}

View File

@ -27,35 +27,44 @@ type OidcAuthConfig struct {
}
type UserPassAuthConfig struct {
HashingAlgorithm string `yaml:"hashing_algorithm"`
Salt string `yaml:"salt"`
Type DatabaseType `yaml:"type"`
Mongo *MongoDBConfig `yaml:"mongo"`
}
type AuthorizationConfig struct {
Type string `yaml:"type"`
type AuthenticationConfig struct {
Type AuthMode `yaml:"type"`
Oidc OidcAuthConfig `yaml:"oidc"`
UserPass UserPassAuthConfig `yaml:"user_pass"`
}
type AuthentikDBConfig struct {
}
type ServersDatabaseConfig struct {
Type string `yaml:"type"`
type UsersDatabaseConfig struct {
Type DatabaseType `yaml:"type"`
Mongo *MongoDBConfig `yaml:"mongo"`
}
type UsersDatabaseConfig struct {
Type string `yaml:"type"`
Mongo *MongoDBConfig `yaml:"mongo"`
Authentik *AuthentikDBConfig `yaml:"authentik"`
type ServersInstanceManagerConfig struct {
Type InstanceManagerType
}
type ServersDatabaseConfig struct {
Type DatabaseType `yaml:"type"`
Mongo *MongoDBConfig `yaml:"mongo"`
}
type ServersAuthorizationDatabaseConfig struct {
Type DatabaseType `yaml:"type"`
Mongo *MongoDBConfig `yaml:"mongo"`
}
type GlobalConfig struct {
Email EmailConfig `yaml:"email"`
Signing SigningConfig `yaml:"signing"`
ServersDatabase ServersDatabaseConfig `yaml:"servers_database"`
UsersDatabase UsersDatabaseConfig `yaml:"users_database"`
Domain string `yaml:"domain"`
Auth AuthorizationConfig `yaml:"auth"`
// Features Configs
Email EmailConfig `yaml:"email"`
Domain string `yaml:"domain"`
Signing SigningConfig `yaml:"signing"`
Authentication AuthenticationConfig `yaml:"authentication"`
// Database Configs
ServersDatabase ServersDatabaseConfig `yaml:"servers_database"`
UsersDatabase UsersDatabaseConfig `yaml:"users_database"`
ServersAuthorizationDatabase ServersAuthorizationDatabaseConfig `yaml:"servers_authorization_database"`
}

View File

@ -1,41 +1,24 @@
package models
type PortProtocol string
const (
TCP PortProtocol = "TCP"
UDP = "UDP"
)
type Port struct {
Protocol string
Number int
Protocol PortProtocol
PublicPort uint16
ContainerPort uint16
}
type ImageInfo struct {
Name string
Version string
Ports []Port
type Image struct {
Registry string
Tag string
}
type ServerInfo struct {
Id string
OwnerId string
DefaultCommand string
Image ImageInfo
On bool
Nickname string
Ports []Port
Domain string
}
type FileBrowserInfo struct {
Id string
OwnerId string
ConnectedTo ServerInfo
Url string
}
type ServerData struct {
Id string `bson:"Id"`
OwnerId string `bson:"OwnerId"`
Image string `bson:"Image"`
VolumeId string `bson:"VolumeId"`
Nickname string `bson:"Nickname"`
UserPermissions map[string]Permission `bson:"UserPermissions"`
DefaultCommand string `bson:"DefaultCommand"`
DefaultPorts []Port `bson:"DefaultPorts"`
type FileBrowser struct {
Id string
Url string
}

14
models/types.go Normal file
View File

@ -0,0 +1,14 @@
package models
type DatabaseType string
const (
MONGO DatabaseType = "mongo"
)
type InstanceManagerType string
const (
KUBERNETES InstanceManagerType = "kubernetes"
DOCKER InstanceManagerType = "docker"
)

View File

@ -15,7 +15,7 @@ import (
"go.mongodb.org/mongo-driver/mongo"
)
func (con Connection) getBrowserInfo(volume volume.Volume) (*models.FileBrowserInfo, error) {
func (con Connection) getBrowserInfo(volume volume.Volume) (*models.FileBrowser, error) {
serverInfo, err := con.getServerInfo(volume)
if err != nil {
return nil, err
@ -42,7 +42,7 @@ func (con Connection) getBrowserInfo(volume volume.Volume) (*models.FileBrowserI
return nil, err
}
return &models.FileBrowserInfo{
return &models.FileBrowser{
Id: serverInfo.Id,
OwnerId: browserInfo.OwnerId,
ConnectedTo: *serverInfo,
@ -50,7 +50,7 @@ func (con Connection) getBrowserInfo(volume volume.Volume) (*models.FileBrowserI
}, nil
}
func (con Connection) getBrowserInfoFromServerId(serverId string) (*models.FileBrowserInfo, error) {
func (con Connection) getBrowserInfoFromServerId(serverId string) (*models.FileBrowser, error) {
serverInfo, err := con.getServerInfoFromId(serverId)
if err != nil {
return nil, err
@ -77,7 +77,7 @@ func (con Connection) getBrowserInfoFromServerId(serverId string) (*models.FileB
return nil, err
}
return &models.FileBrowserInfo{
return &models.FileBrowser{
Id: serverInfo.Id,
OwnerId: browserInfo.OwnerId,
ConnectedTo: *serverInfo,
@ -97,7 +97,7 @@ func (con Connection) GetBrowsers(ctx *gin.Context) {
ctx.AbortWithError(500, err)
}
var servers []models.FileBrowserInfo = make([]models.FileBrowserInfo, 0, len(volumes.Volumes))
var servers []models.FileBrowser = make([]models.FileBrowser, 0, len(volumes.Volumes))
for _, volume := range volumes.Volumes {
browserInfo, err := con.getBrowserInfo(*volume)

View File

@ -128,7 +128,7 @@ func (con Connection) getServerInfo(volume volume.Volume) (*models.ServerInfo, e
serverInfo := models.ServerInfo{
Id: volume.Name,
Image: models.ImageInfo{
Image: models.Image{
Name: imageName,
Version: imageVersion,
Ports: imagePorts,