mirror of
https://github.com/bytedream/docker4ssh.git
synced 2025-05-09 12:15:11 +02:00
125 lines
3.5 KiB
Go
125 lines
3.5 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"docker4ssh/docker"
|
|
"docker4ssh/ssh"
|
|
"encoding/json"
|
|
"fmt"
|
|
"go.uber.org/zap"
|
|
"net/http"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
type configGetResponse struct {
|
|
NetworkMode docker.NetworkMode `json:"network_mode"`
|
|
Configurable bool `json:"configurable"`
|
|
RunLevel docker.RunLevel `json:"run_level"`
|
|
StartupInformation bool `json:"startup_information"`
|
|
ExitAfter string `json:"exit_after"`
|
|
KeepOnExit bool `json:"keep_on_exit"`
|
|
}
|
|
|
|
func ConfigGet(w http.ResponseWriter, r *http.Request, user *ssh.User) (interface{}, int) {
|
|
config := user.Container.Config()
|
|
|
|
return configGetResponse{
|
|
config.NetworkMode,
|
|
config.Configurable,
|
|
config.RunLevel,
|
|
config.StartupInformation,
|
|
config.ExitAfter,
|
|
config.KeepOnExit,
|
|
}, http.StatusOK
|
|
}
|
|
|
|
type configPostRequest configGetResponse
|
|
|
|
var configPostRequestLookup, _ = structJsonLookup(configPostRequest{})
|
|
|
|
type configPostResponse struct {
|
|
Message string `json:"message"`
|
|
Rejected []configPostResponseRejected `json:"rejected"`
|
|
}
|
|
|
|
type configPostResponseRejected struct {
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
}
|
|
|
|
func ConfigPost(w http.ResponseWriter, r *http.Request, user *ssh.User) (interface{}, int) {
|
|
var requestBody map[string]interface{}
|
|
json.NewDecoder(r.Body).Decode(&requestBody)
|
|
defer r.Body.Close()
|
|
|
|
var change bool
|
|
var response configPostResponse
|
|
|
|
updatedConfig := user.Container.Config()
|
|
|
|
for k, v := range requestBody {
|
|
if v == nil {
|
|
continue
|
|
}
|
|
|
|
kind, ok := configPostRequestLookup[k]
|
|
if !ok {
|
|
response.Rejected = append(response.Rejected, configPostResponseRejected{
|
|
Name: k,
|
|
Description: fmt.Sprintf("name / field %s does not exist", k),
|
|
})
|
|
} else {
|
|
valueKind := reflect.TypeOf(v).Kind()
|
|
if valueKind != kind && valueKind == reflect.Float64 && kind == reflect.Int {
|
|
valueKind = reflect.Int
|
|
}
|
|
|
|
if valueKind != kind {
|
|
response.Rejected = append(response.Rejected, configPostResponseRejected{
|
|
Name: k,
|
|
Description: fmt.Sprintf("value should be type %s, got type %s", kind, valueKind),
|
|
})
|
|
}
|
|
|
|
change = true
|
|
switch k {
|
|
case "network_mode":
|
|
updatedConfig.NetworkMode = docker.NetworkMode(v.(float64))
|
|
case "configurable":
|
|
updatedConfig.Configurable = v.(bool)
|
|
case "run_level":
|
|
updatedConfig.RunLevel = docker.RunLevel(v.(float64))
|
|
case "startup_information":
|
|
updatedConfig.StartupInformation = v.(bool)
|
|
case "exit_after":
|
|
updatedConfig.ExitAfter = v.(string)
|
|
case "keep_on_exit":
|
|
updatedConfig.KeepOnExit = v.(bool)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(response.Rejected) > 0 {
|
|
var arr []string
|
|
for _, rejected := range response.Rejected {
|
|
arr = append(arr, rejected.Name)
|
|
}
|
|
|
|
if len(response.Rejected) == 1 {
|
|
response.Message = fmt.Sprintf("1 invalid configuration was found: %s", strings.Join(arr, ", "))
|
|
return response, http.StatusNotAcceptable
|
|
} else if len(response.Rejected) > 1 {
|
|
response.Message = fmt.Sprintf("%d invalid configurations were found: %s", len(response.Rejected), strings.Join(arr, ", "))
|
|
return response, http.StatusNotAcceptable
|
|
}
|
|
} else if change {
|
|
if err := user.Container.UpdateConfig(context.Background(), updatedConfig); err != nil {
|
|
zap.S().Errorf("Error while updating config for API user %s: %v", user.ID, err)
|
|
response.Message = "Internal error while updating the config"
|
|
return response, http.StatusInternalServerError
|
|
}
|
|
}
|
|
return nil, http.StatusOK
|
|
}
|