feat: wireguard / vproxy configuration
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
PRIVKEY=odkqwjdoqwjdoi
|
||||||
|
VIP=127.0.0.1
|
||||||
|
PSK=qowdjoqwijdoqwi
|
||||||
|
PROXY_EDPS=qodjoqwjdoqwij
|
||||||
|
|
||||||
|
# MTU Opcional
|
||||||
|
MTU=1380
|
||||||
|
|
||||||
|
# Especifica o protocolo de transmissao
|
||||||
|
# Default: UDP -> Manter se possivel, melhor performance e estabilidade.
|
||||||
|
# Alguns firewalls restritivos podem impedir o trafego UDP.
|
||||||
|
# Se nao for possivel negociar a abertura com o cliente, tentar usar TCP
|
||||||
|
PROTO=UDP
|
||||||
@@ -6,6 +6,7 @@ require (
|
|||||||
charm.land/bubbles/v2 v2.0.0
|
charm.land/bubbles/v2 v2.0.0
|
||||||
charm.land/bubbletea/v2 v2.0.1
|
charm.land/bubbletea/v2 v2.0.1
|
||||||
charm.land/lipgloss/v2 v2.0.0
|
charm.land/lipgloss/v2 v2.0.0
|
||||||
|
github.com/BurntSushi/toml v1.6.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ charm.land/bubbletea/v2 v2.0.1 h1:B8e9zzK7x9JJ+XvHGF4xnYu9Xa0E0y0MyggY6dbaCfQ=
|
|||||||
charm.land/bubbletea/v2 v2.0.1/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ=
|
charm.land/bubbletea/v2 v2.0.1/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ=
|
||||||
charm.land/lipgloss/v2 v2.0.0 h1:sd8N/B3x892oiOjFfBQdXBQp3cAkvjGaU5TvVZC3ivo=
|
charm.land/lipgloss/v2 v2.0.0 h1:sd8N/B3x892oiOjFfBQdXBQp3cAkvjGaU5TvVZC3ivo=
|
||||||
charm.land/lipgloss/v2 v2.0.0/go.mod h1:w6SnmsBFBmEFBodiEDurGS/sdUY/u1+v72DqUzc6J14=
|
charm.land/lipgloss/v2 v2.0.0/go.mod h1:w6SnmsBFBmEFBodiEDurGS/sdUY/u1+v72DqUzc6J14=
|
||||||
|
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
|
||||||
|
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||||
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||||
github.com/aymanbagabas/go-udiff v0.4.0 h1:TKnLPh7IbnizJIBKFWa9mKayRUBQ9Kh1BPCk6w2PnYM=
|
github.com/aymanbagabas/go-udiff v0.4.0 h1:TKnLPh7IbnizJIBKFWa9mKayRUBQ9Kh1BPCk6w2PnYM=
|
||||||
|
|||||||
@@ -65,6 +65,28 @@ func DownloadImageCmd(username, password string) tea.Cmd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DownloadWireguardImageCmd(username, password string) tea.Cmd {
|
||||||
|
return func() tea.Msg {
|
||||||
|
url := wireguardImageName
|
||||||
|
|
||||||
|
loginOut, err := exec.Command(
|
||||||
|
"docker", "login", url,
|
||||||
|
"-u", username,
|
||||||
|
"-p", password,
|
||||||
|
).CombinedOutput()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return ImageDownloadFinishedMsg{
|
||||||
|
Message: string(loginOut),
|
||||||
|
Err: fmt.Errorf("falha no login: %w", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message, err := PullImage(url)
|
||||||
|
return ImageDownloadFinishedMsg{Message: message, Err: err}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func CheckImageCmd(image string) tea.Cmd {
|
func CheckImageCmd(image string) tea.Cmd {
|
||||||
return func() tea.Msg {
|
return func() tea.Msg {
|
||||||
cmd := exec.Command("docker", "image", "inspect", image)
|
cmd := exec.Command("docker", "image", "inspect", image)
|
||||||
@@ -77,6 +99,16 @@ func CheckImageCmd(image string) tea.Cmd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenerateWireguardConfigFile(cv ConfigValues, path string) tea.Cmd {
|
||||||
|
return func() tea.Msg {
|
||||||
|
err := WriteWireguardConfigFile(cv, path)
|
||||||
|
|
||||||
|
return ConfigFileMsg{
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func GenerateConfigFile(cv ConfigValues, path string) tea.Cmd {
|
func GenerateConfigFile(cv ConfigValues, path string) tea.Cmd {
|
||||||
return func() tea.Msg {
|
return func() tea.Msg {
|
||||||
err := WriteConfigFile(cv, path)
|
err := WriteConfigFile(cv, path)
|
||||||
@@ -96,3 +128,13 @@ func RunAppContainer(image, name, filePath, destinationPath string, cv ConfigVal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RunWireguardContainer(path string, cv ConfigValues) tea.Cmd {
|
||||||
|
return func() tea.Msg {
|
||||||
|
err := RunWireguardDockerContainer(path, cv)
|
||||||
|
|
||||||
|
return DockerRunMsg{
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ func GenerateConfigTOML(cv ConfigValues) (string, error) {
|
|||||||
// [certificate]
|
// [certificate]
|
||||||
sb.WriteString("# Certificate Options\n")
|
sb.WriteString("# Certificate Options\n")
|
||||||
sb.WriteString("[certificate]\n")
|
sb.WriteString("[certificate]\n")
|
||||||
|
sb.WriteString(fmt.Sprintf("mapped_dir = %q\n", cv.Cert["cert_dir_path"]))
|
||||||
sb.WriteString(fmt.Sprintf("cert_path = %q\n", "/app/certs/"+cv.Cert["cert_name"]))
|
sb.WriteString(fmt.Sprintf("cert_path = %q\n", "/app/certs/"+cv.Cert["cert_name"]))
|
||||||
sb.WriteString(fmt.Sprintf("key_path = %q\n", "/app/certs/"+cv.Cert["key_name"]))
|
sb.WriteString(fmt.Sprintf("key_path = %q\n", "/app/certs/"+cv.Cert["key_name"]))
|
||||||
sb.WriteString(fmt.Sprintf("ca_path = %q\n", "/app/certs/"+cv.Cert["ca_name"]))
|
sb.WriteString(fmt.Sprintf("ca_path = %q\n", "/app/certs/"+cv.Cert["ca_name"]))
|
||||||
@@ -52,6 +53,36 @@ func GenerateConfigTOML(cv ConfigValues) (string, error) {
|
|||||||
return sb.String(), nil
|
return sb.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenerateWireguardConfig(cv ConfigValues) (string, error) {
|
||||||
|
var sb strings.Builder
|
||||||
|
|
||||||
|
// Primary Wireguard Settings
|
||||||
|
sb.WriteString(fmt.Sprintf("PRIVKEY=%s\n", cv.Wireguard["privkey"]))
|
||||||
|
sb.WriteString(fmt.Sprintf("VIP=%s\n", cv.Wireguard["vip"]))
|
||||||
|
sb.WriteString(fmt.Sprintf("PSK=%s\n", cv.Wireguard["psk"]))
|
||||||
|
sb.WriteString(fmt.Sprintf("PROXY_EDPS=%s\n", cv.Wireguard["proxy_edps"]))
|
||||||
|
|
||||||
|
sb.WriteString("\n# MTU Opcional\n")
|
||||||
|
if mtu, ok := cv.Wireguard["mtu"]; ok && mtu != "" {
|
||||||
|
sb.WriteString(fmt.Sprintf("MTU=%s\n", mtu))
|
||||||
|
} else {
|
||||||
|
sb.WriteString("# MTU=1380\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.WriteString("\n# Especifica o protocolo de transmissao\n")
|
||||||
|
sb.WriteString("# Default: UDP -> Manter se possivel, melhor performance e estabilidade.\n")
|
||||||
|
sb.WriteString("# Alguns firewalls restritivos podem impedir o trafego UDP.\n")
|
||||||
|
sb.WriteString("# Se nao for possivel negociar a abertura com o cliente, tentar usar TCP\n")
|
||||||
|
|
||||||
|
proto := cv.Wireguard["proto"]
|
||||||
|
if proto == "" {
|
||||||
|
proto = "UDP"
|
||||||
|
}
|
||||||
|
sb.WriteString(fmt.Sprintf("PROTO=%s\n", proto))
|
||||||
|
|
||||||
|
return sb.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func WriteConfigFile(cv ConfigValues, path string) error {
|
func WriteConfigFile(cv ConfigValues, path string) error {
|
||||||
// Validate numeric fields before writing
|
// Validate numeric fields before writing
|
||||||
numericFields := map[string]string{
|
numericFields := map[string]string{
|
||||||
@@ -73,3 +104,19 @@ func WriteConfigFile(cv ConfigValues, path string) error {
|
|||||||
|
|
||||||
return os.WriteFile(path, []byte(content), 0644)
|
return os.WriteFile(path, []byte(content), 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WriteWireguardConfigFile(cv ConfigValues, path string) error {
|
||||||
|
// Validate numeric fields before writing
|
||||||
|
if mtu, ok := cv.Wireguard["mtu"]; ok && mtu != "" {
|
||||||
|
if _, err := strconv.Atoi(mtu); err != nil {
|
||||||
|
return fmt.Errorf("o campo MTU deve ser um número, recebido: %q", mtu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := GenerateWireguardConfig(cv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.WriteFile(path, []byte(content), 0644)
|
||||||
|
}
|
||||||
|
|||||||
@@ -45,6 +45,39 @@ func PushFileToContainer(container, filePath, destinationPath string) bool {
|
|||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RunWireguardDockerContainer(envFilePath string, cv ConfigValues) error {
|
||||||
|
containerName := "vproxy"
|
||||||
|
|
||||||
|
removeExistingContainer(containerName)
|
||||||
|
|
||||||
|
absPath, err := filepath.Abs(envFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("erro ao resolver caminho absoluto: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(
|
||||||
|
"docker", "run", "-it", "-d",
|
||||||
|
"--name", containerName,
|
||||||
|
"--network", "app-dono_app",
|
||||||
|
"--restart", "unless-stopped",
|
||||||
|
"--cap-add=NET_ADMIN",
|
||||||
|
"--device", "/dev/net/tun:/dev/net/tun",
|
||||||
|
"--log-opt", "max-size=5m",
|
||||||
|
"--log-opt", "max-file=1",
|
||||||
|
"--env-file", absPath,
|
||||||
|
wireguardImageName,
|
||||||
|
)
|
||||||
|
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("docker run falhou: %w\noutput: %s", err, string(out))
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
containerID := strings.TrimSpace(string(out))
|
||||||
|
return verifyContainerRunning(containerID)
|
||||||
|
}
|
||||||
|
|
||||||
func RunAppClienteContainer(image, containerName, configPath, configDestinationPath string, cv ConfigValues) error {
|
func RunAppClienteContainer(image, containerName, configPath, configDestinationPath string, cv ConfigValues) error {
|
||||||
removeExistingContainer(containerName)
|
removeExistingContainer(containerName)
|
||||||
|
|
||||||
|
|||||||
+119
-17
@@ -1,8 +1,14 @@
|
|||||||
package tui
|
package tui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"charm.land/bubbles/v2/spinner"
|
"charm.land/bubbles/v2/spinner"
|
||||||
tea "charm.land/bubbletea/v2"
|
tea "charm.land/bubbletea/v2"
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Model struct {
|
type Model struct {
|
||||||
@@ -24,6 +30,7 @@ type Model struct {
|
|||||||
isPublicIP bool
|
isPublicIP bool
|
||||||
|
|
||||||
loginForm FormStep
|
loginForm FormStep
|
||||||
|
wireguardForm FormStep
|
||||||
serverForm FormStep
|
serverForm FormStep
|
||||||
dbForm FormStep
|
dbForm FormStep
|
||||||
certForm FormStep
|
certForm FormStep
|
||||||
@@ -44,12 +51,70 @@ type DockerLoginData struct {
|
|||||||
|
|
||||||
type ConfigValues struct {
|
type ConfigValues struct {
|
||||||
Login map[string]string
|
Login map[string]string
|
||||||
|
Wireguard map[string]string
|
||||||
Server map[string]string
|
Server map[string]string
|
||||||
Database map[string]string
|
Database map[string]string
|
||||||
Cert map[string]string
|
Cert map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AppConfig struct {
|
||||||
|
Server struct {
|
||||||
|
Port int64 `toml:"port"`
|
||||||
|
Timeout int64 `toml:"timeout_seconds"`
|
||||||
|
Environment string `toml:"environment"`
|
||||||
|
} `toml:"server"`
|
||||||
|
Database struct {
|
||||||
|
Type string `toml:"type"`
|
||||||
|
URL string `toml:"url"`
|
||||||
|
MaxConns int64 `toml:"max_conns"`
|
||||||
|
MinConns int64 `toml:"min_conns"`
|
||||||
|
} `toml:"database"`
|
||||||
|
Certificates struct {
|
||||||
|
DirPath string `toml:"mapped_dir"`
|
||||||
|
CertName string `toml:"cert_path"`
|
||||||
|
KeyName string `toml:"key_path"`
|
||||||
|
CAName string `toml:"ca_path"`
|
||||||
|
ServerName string `toml:"server_name"`
|
||||||
|
} `toml:"certificate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConfig() AppConfig {
|
||||||
|
var config AppConfig
|
||||||
|
|
||||||
|
config.Server.Port = 8081
|
||||||
|
config.Server.Timeout = 30
|
||||||
|
config.Server.Environment = "production"
|
||||||
|
|
||||||
|
config.Database.Type = "postgres"
|
||||||
|
config.Database.URL = "postgres://usuario:senha@banco:5432/app_dono_db"
|
||||||
|
config.Database.MaxConns = 10
|
||||||
|
config.Database.MinConns = 2
|
||||||
|
|
||||||
|
config.Certificates.DirPath = "/caminho/para/diretorio"
|
||||||
|
config.Certificates.CertName = "certificado.crt"
|
||||||
|
config.Certificates.KeyName = "chave.key"
|
||||||
|
config.Certificates.CAName = "chaveCA.crt"
|
||||||
|
config.Certificates.ServerName = "client"
|
||||||
|
|
||||||
|
_, err := os.Stat("config.toml")
|
||||||
|
if err == nil {
|
||||||
|
if _, err := toml.DecodeFile("config.toml", &config); err != nil {
|
||||||
|
fmt.Printf("Error loading config: %v\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
config.Certificates.CertName = filepath.Base(config.Certificates.CertName)
|
||||||
|
config.Certificates.KeyName = filepath.Base(config.Certificates.KeyName)
|
||||||
|
config.Certificates.CAName = filepath.Base(config.Certificates.CAName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
func InitialModel() Model {
|
func InitialModel() Model {
|
||||||
|
cfg := loadConfig()
|
||||||
|
|
||||||
s := spinner.New()
|
s := spinner.New()
|
||||||
s.Spinner = spinner.Dot
|
s.Spinner = spinner.Dot
|
||||||
s.Style = SpinnerStyle
|
s.Style = SpinnerStyle
|
||||||
@@ -70,12 +135,53 @@ func InitialModel() Model {
|
|||||||
Type: FieldTypePassword,
|
Type: FieldTypePassword,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
wireguardForm: NewFormStep("Configurações vproxy", []FormField{
|
||||||
|
{
|
||||||
|
Id: "privkey",
|
||||||
|
Label: "Chave Privada",
|
||||||
|
Placeholder: "",
|
||||||
|
Type: FieldTypeText,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "vip",
|
||||||
|
Label: "IP Virtual",
|
||||||
|
Default: "127.0.0.1",
|
||||||
|
Placeholder: "127.0.0.1",
|
||||||
|
Type: FieldTypeText,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "psk",
|
||||||
|
Label: "Pre-Shared Key",
|
||||||
|
Placeholder: "",
|
||||||
|
Type: FieldTypeText,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "proxy_edps",
|
||||||
|
Label: "Proxy EDPS",
|
||||||
|
Placeholder: "22:127.0.0.1:22",
|
||||||
|
Type: FieldTypeText,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "mtu",
|
||||||
|
Label: "MTU",
|
||||||
|
Default: "1380",
|
||||||
|
Placeholder: "1380",
|
||||||
|
Type: FieldTypeNumber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "proto",
|
||||||
|
Label: "Protocolo",
|
||||||
|
Default: "UDP",
|
||||||
|
Type: FieldTypeSelect,
|
||||||
|
Options: []string{"UDP", "TCP"},
|
||||||
|
},
|
||||||
|
}),
|
||||||
serverForm: NewFormStep("Servidor", []FormField{
|
serverForm: NewFormStep("Servidor", []FormField{
|
||||||
{
|
{
|
||||||
Id: "port",
|
Id: "port",
|
||||||
Label: "Porta",
|
Label: "Porta",
|
||||||
Placeholder: "8081",
|
Placeholder: "8081",
|
||||||
Default: "8081",
|
Default: strconv.FormatInt(cfg.Server.Port, 10),
|
||||||
Type: FieldTypeNumber,
|
Type: FieldTypeNumber,
|
||||||
CharLimit: 4,
|
CharLimit: 4,
|
||||||
},
|
},
|
||||||
@@ -83,14 +189,14 @@ func InitialModel() Model {
|
|||||||
Id: "timeout",
|
Id: "timeout",
|
||||||
Label: "Timeout (Segundos)",
|
Label: "Timeout (Segundos)",
|
||||||
Placeholder: "30",
|
Placeholder: "30",
|
||||||
Default: "30",
|
Default: strconv.FormatInt(cfg.Server.Timeout, 10),
|
||||||
Type: FieldTypeNumber,
|
Type: FieldTypeNumber,
|
||||||
CharLimit: 3,
|
CharLimit: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Id: "environment",
|
Id: "environment",
|
||||||
Label: "Ambiente",
|
Label: "Ambiente",
|
||||||
Default: "production",
|
Default: cfg.Server.Environment,
|
||||||
Type: FieldTypeSelect,
|
Type: FieldTypeSelect,
|
||||||
Options: []string{"development", "production"},
|
Options: []string{"development", "production"},
|
||||||
},
|
},
|
||||||
@@ -99,7 +205,7 @@ func InitialModel() Model {
|
|||||||
{
|
{
|
||||||
Id: "database_type",
|
Id: "database_type",
|
||||||
Label: "Tipo do Banco",
|
Label: "Tipo do Banco",
|
||||||
Default: "postgres",
|
Default: cfg.Database.Type,
|
||||||
Type: FieldTypeSelect,
|
Type: FieldTypeSelect,
|
||||||
Options: []string{"postgres", "oracle"},
|
Options: []string{"postgres", "oracle"},
|
||||||
},
|
},
|
||||||
@@ -107,58 +213,54 @@ func InitialModel() Model {
|
|||||||
Id: "database_url",
|
Id: "database_url",
|
||||||
Label: "URL de acesso",
|
Label: "URL de acesso",
|
||||||
Placeholder: "postgres://usuario:senha@banco:5432/app_dono_db",
|
Placeholder: "postgres://usuario:senha@banco:5432/app_dono_db",
|
||||||
Default: "postgres://usuario:senha@banco:5432/app_dono_db",
|
Default: cfg.Database.URL,
|
||||||
Type: FieldTypeText,
|
Type: FieldTypeText,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Id: "max_conns",
|
Id: "max_conns",
|
||||||
Label: "Conexões ativas (máximo)",
|
Label: "Conexões ativas (máximo)",
|
||||||
Placeholder: "10",
|
Placeholder: "10",
|
||||||
Default: "10",
|
Default: strconv.FormatInt(cfg.Database.MaxConns, 10),
|
||||||
Type: FieldTypeNumber,
|
Type: FieldTypeNumber,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Id: "min_conns",
|
Id: "min_conns",
|
||||||
Label: "Conexões ativas (mínimo)",
|
Label: "Conexões ativas (mínimo)",
|
||||||
Placeholder: "2",
|
Placeholder: "2",
|
||||||
Default: "2",
|
Default: strconv.FormatInt(cfg.Database.MinConns, 10),
|
||||||
Type: FieldTypeNumber,
|
Type: FieldTypeNumber,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
certForm: NewFormStep("Certificado", []FormField{
|
certForm: NewFormStep("Certificado", []FormField{
|
||||||
{
|
{
|
||||||
Id: "cert_dir_path",
|
Id: "cert_dir_path",
|
||||||
Label: "Caminho para o diretório dos certificados (será montado no container)",
|
Label: "Caminho para o diretório dos certificados",
|
||||||
Placeholder: "/caminho/para/diretorio",
|
Placeholder: "/caminho/para/diretorio",
|
||||||
Default: "/caminho/para/diretorio",
|
Default: cfg.Certificates.DirPath,
|
||||||
Type: FieldTypeText,
|
Type: FieldTypeText,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Id: "cert_name",
|
Id: "cert_name",
|
||||||
Label: "Nome do arquivo do certificado",
|
Label: "Nome do arquivo do certificado",
|
||||||
Placeholder: "certificado.crt",
|
Default: cfg.Certificates.CertName,
|
||||||
Default: "certificado.crt",
|
|
||||||
Type: FieldTypeText,
|
Type: FieldTypeText,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Id: "key_name",
|
Id: "key_name",
|
||||||
Label: "Nome do arquivo da chave",
|
Label: "Nome do arquivo da chave",
|
||||||
Placeholder: "chave.key",
|
Default: cfg.Certificates.KeyName,
|
||||||
Default: "chave.key",
|
|
||||||
Type: FieldTypeText,
|
Type: FieldTypeText,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Id: "ca_name",
|
Id: "ca_name",
|
||||||
Label: "Nome do arquivo da autoridade certificadora",
|
Label: "Nome do arquivo da autoridade certificadora",
|
||||||
Placeholder: "chaveCA.crt",
|
Default: cfg.Certificates.CAName,
|
||||||
Default: "chaveCA.crt",
|
|
||||||
Type: FieldTypeText,
|
Type: FieldTypeText,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Id: "server_name",
|
Id: "server_name",
|
||||||
Label: "Nome do servidor",
|
Label: "Nome do servidor",
|
||||||
Placeholder: "client",
|
Default: cfg.Certificates.ServerName,
|
||||||
Default: "client",
|
|
||||||
Type: FieldTypeText,
|
Type: FieldTypeText,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ const (
|
|||||||
|
|
||||||
// IP Stuff
|
// IP Stuff
|
||||||
StepIPQuestion
|
StepIPQuestion
|
||||||
StepInstallWireguard
|
StepWireguardConfig
|
||||||
|
StepGenerateWireguardFile
|
||||||
|
StepDownloadWireguard
|
||||||
|
StepRunWireguard
|
||||||
|
|
||||||
// Docker Config
|
// Docker Config
|
||||||
StepServerConfig
|
StepServerConfig
|
||||||
|
|||||||
+98
-3
@@ -10,7 +10,9 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
imageName = "hub.davinti.com.br:443/app-dono/app-cliente:latest"
|
imageName = "hub.davinti.com.br:443/app-dono/app-cliente:latest"
|
||||||
|
wireguardImageName = "hub.davinti.com.br:443/davinti-vproxy:latest"
|
||||||
configPath = "config.toml"
|
configPath = "config.toml"
|
||||||
|
wireguardConfigPath = "envs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
@@ -49,10 +51,32 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return m, cmd
|
return m, cmd
|
||||||
case StepDownloadImage:
|
case StepDownloadImage:
|
||||||
return m.updateDownloadImage(msg)
|
return m.updateDownloadImage(msg)
|
||||||
|
|
||||||
|
// Ip & Wireguard
|
||||||
case StepIPQuestion:
|
case StepIPQuestion:
|
||||||
return m.updateIPQuestion(msg)
|
return m.updateIPQuestion(msg)
|
||||||
//case StepInstallWireguard
|
case StepWireguardConfig:
|
||||||
// return m.updateInstallWireguard(msg)
|
done, cmd := m.wireguardForm.Update(msg)
|
||||||
|
|
||||||
|
if done {
|
||||||
|
m.configValues.Wireguard = m.wireguardForm.Values()
|
||||||
|
|
||||||
|
m.downloadDone = false
|
||||||
|
m.downloadMessage = ""
|
||||||
|
m.downloadError = nil
|
||||||
|
m.currentStep = StepGenerateWireguardFile
|
||||||
|
|
||||||
|
return m, GenerateWireguardConfigFile(m.configValues, wireguardConfigPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return m, cmd
|
||||||
|
case StepGenerateWireguardFile:
|
||||||
|
return m.updateGenerateWireguardFile(msg)
|
||||||
|
case StepDownloadWireguard:
|
||||||
|
return m.updateDownloadWireguard(msg)
|
||||||
|
case StepRunWireguard:
|
||||||
|
return m.updateRunWireguardDocker(msg)
|
||||||
|
|
||||||
case StepServerConfig:
|
case StepServerConfig:
|
||||||
done, cmd := m.serverForm.Update(msg)
|
done, cmd := m.serverForm.Update(msg)
|
||||||
|
|
||||||
@@ -78,6 +102,9 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
m.configValues.Cert = m.certForm.Values()
|
m.configValues.Cert = m.certForm.Values()
|
||||||
m.currentStep = StepGenerateFile
|
m.currentStep = StepGenerateFile
|
||||||
|
|
||||||
|
m.finishedFile = false
|
||||||
|
m.configFileError = nil
|
||||||
|
|
||||||
return m, GenerateConfigFile(m.configValues, configPath)
|
return m, GenerateConfigFile(m.configValues, configPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,8 +196,73 @@ func (m Model) updateIPQuestion(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
m.currentStep = StepInstallWireguard
|
m.currentStep = StepWireguardConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return m, nil
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) updateDownloadWireguard(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case ImageDownloadFinishedMsg:
|
||||||
|
m.downloadDone = true
|
||||||
|
m.downloadMessage = msg.Message
|
||||||
|
m.downloadError = msg.Err
|
||||||
|
|
||||||
|
if m.downloadError == nil {
|
||||||
|
m.currentStep = StepRunWireguard
|
||||||
|
|
||||||
|
return m, RunWireguardContainer(wireguardConfigPath, m.configValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
case tea.KeyPressMsg:
|
||||||
|
if m.downloadDone && m.downloadError == nil {
|
||||||
|
m.currentStep = StepRunWireguard
|
||||||
|
} else if m.downloadDone {
|
||||||
|
return m, tea.Quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) updateGenerateWireguardFile(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case ConfigFileMsg:
|
||||||
|
m.finishedFile = true
|
||||||
|
m.configFileError = msg.Err
|
||||||
|
|
||||||
|
if msg.Err == nil {
|
||||||
|
m.currentStep = StepDownloadWireguard
|
||||||
|
|
||||||
|
return m, DownloadWireguardImageCmd(m.configValues.Login["user"], m.configValues.Login["password"])
|
||||||
|
}
|
||||||
|
|
||||||
|
case tea.KeyPressMsg:
|
||||||
|
if m.finishedFile && m.configFileError != nil {
|
||||||
|
return m, tea.Quit
|
||||||
|
} else if m.finishedFile && m.configFileError == nil {
|
||||||
|
m.currentStep = StepDownloadWireguard
|
||||||
|
|
||||||
|
return m, DownloadWireguardImageCmd(m.configValues.Login["user"], m.configValues.Login["password"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) updateRunWireguardDocker(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case DockerRunMsg:
|
||||||
|
m.finishedDockerRun = true
|
||||||
|
m.dockerRunError = msg.Err
|
||||||
|
|
||||||
|
case tea.KeyPressMsg:
|
||||||
|
if m.finishedDockerRun && m.dockerRunError != nil {
|
||||||
|
return m, tea.Quit
|
||||||
|
} else if m.finishedDockerRun && m.dockerRunError == nil {
|
||||||
|
m.currentStep = StepServerConfig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,6 +281,9 @@ func (m Model) updateGenerateFile(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
} else if m.finishedFile && m.configFileError == nil {
|
} else if m.finishedFile && m.configFileError == nil {
|
||||||
m.currentStep = StepRunDocker
|
m.currentStep = StepRunDocker
|
||||||
|
|
||||||
|
m.finishedDockerRun = false
|
||||||
|
m.dockerRunError = nil
|
||||||
|
|
||||||
return m, RunAppContainer(
|
return m, RunAppContainer(
|
||||||
imageName,
|
imageName,
|
||||||
"app-dono-cliente",
|
"app-dono-cliente",
|
||||||
|
|||||||
@@ -36,6 +36,21 @@ func (m Model) View() tea.View {
|
|||||||
// IP Stuff
|
// IP Stuff
|
||||||
case StepIPQuestion:
|
case StepIPQuestion:
|
||||||
body = m.viewIPQuestion()
|
body = m.viewIPQuestion()
|
||||||
|
case StepWireguardConfig:
|
||||||
|
body = m.wireguardForm.View()
|
||||||
|
helpMsg = formMsg
|
||||||
|
case StepGenerateWireguardFile:
|
||||||
|
body = m.viewGenerateFile()
|
||||||
|
if m.finishedFile && m.configFileError != nil {
|
||||||
|
helpMsg = anyKeyOutMsg
|
||||||
|
}
|
||||||
|
case StepDownloadWireguard:
|
||||||
|
body = m.viewDownloadImage()
|
||||||
|
case StepRunWireguard:
|
||||||
|
body = m.viewDockerRun()
|
||||||
|
if m.finishedDockerRun && m.dockerRunError != nil {
|
||||||
|
helpMsg = anyKeyOutMsg
|
||||||
|
}
|
||||||
|
|
||||||
// App Config Stuff
|
// App Config Stuff
|
||||||
case StepServerConfig:
|
case StepServerConfig:
|
||||||
|
|||||||
Reference in New Issue
Block a user