Files
elmprodvpn/selective-vpn-api/app/transport_backends_adapter_systemd_provision_inputs.go

129 lines
4.0 KiB
Go

package app
import (
"fmt"
"strings"
"time"
)
type transportSystemdProvisionInputs struct {
unit string
primaryCmd string
cmdSource string
sshOverlay bool
sshUnit string
sshCmd string
primaryTuning transportSystemdServiceTuning
sshTuning transportSystemdServiceTuning
primaryHardening transportSystemdHardening
sshHardening transportSystemdHardening
}
func buildTransportSystemdProvisionInputs(
client TransportClient,
) (transportSystemdProvisionInputs, []string, []string, *transportBackendActionResult) {
unit := transportBackendUnit(client)
if !validSystemdUnitName(unit) {
res := transportBackendActionResult{
OK: false,
Code: "TRANSPORT_BACKEND_UNIT_REQUIRED",
Message: "valid systemd unit is required",
ExitCode: -1,
}
return transportSystemdProvisionInputs{}, nil, nil, &res
}
preOut, preErr, failure := runTransportSystemdProvisionPreflight(client)
if failure != nil {
return transportSystemdProvisionInputs{}, preOut, preErr, failure
}
primaryCmd, cmdSource, err := resolveTransportPrimaryExecStart(client)
if err != nil {
res := transportBackendActionResult{
OK: false,
Code: "TRANSPORT_BACKEND_PROVISION_CONFIG_REQUIRED",
Message: err.Error(),
ExitCode: -1,
}
return transportSystemdProvisionInputs{}, preOut, preErr, &res
}
if transportNetnsEnabled(client) {
primaryCmd = transportWrapExecWithNetns(client, primaryCmd)
}
sshOverlay := transportDNSTTSSHTunnelEnabled(client)
sshUnit := strings.TrimSpace(transportDNSTTSSHUnit(client))
sshCmd := strings.TrimSpace(transportConfigString(client.Config, "ssh_exec_start"))
if sshOverlay && !validSystemdUnitName(sshUnit) {
res := transportBackendActionResult{
OK: false,
Code: "TRANSPORT_BACKEND_PROVISION_CONFIG_REQUIRED",
Message: "valid config.ssh_unit is required when ssh overlay enabled",
ExitCode: -1,
}
return transportSystemdProvisionInputs{}, preOut, preErr, &res
}
if sshOverlay && sshCmd == "" {
overlayCmd, overlayErr := buildTransportSSHOverlayCommand(client.Config)
if overlayErr != nil {
res := transportBackendActionResult{
OK: false,
Code: "TRANSPORT_BACKEND_PROVISION_CONFIG_REQUIRED",
Message: overlayErr.Error(),
ExitCode: -1,
}
return transportSystemdProvisionInputs{}, preOut, preErr, &res
}
sshCmd = overlayCmd
}
in := transportSystemdProvisionInputs{
unit: unit,
primaryCmd: primaryCmd,
cmdSource: cmdSource,
sshOverlay: sshOverlay,
sshUnit: sshUnit,
sshCmd: sshCmd,
primaryTuning: transportSystemdServiceTuningFromConfig(client.Config, ""),
sshTuning: transportSystemdServiceTuningFromConfig(client.Config, "ssh_"),
primaryHardening: transportSystemdHardeningFromConfig(client.Config, ""),
sshHardening: transportSystemdHardeningFromConfig(client.Config, "ssh_"),
}
return in, preOut, preErr, nil
}
func runTransportSystemdProvisionPreflight(
client TransportClient,
) ([]string, []string, *transportBackendActionResult) {
preOut := make([]string, 0, 2)
preErr := make([]string, 0, 2)
if client.Kind != TransportClientSingBox {
return preOut, preErr, nil
}
migMsg, migErr := transportMaybeMigrateSingBoxDNSConfig(client)
if s := strings.TrimSpace(migMsg); s != "" {
preOut = append(preOut, "dns-migrate: "+s)
appendTraceLine("transport", fmt.Sprintf("singbox dns migrate: client=%s %s", client.ID, s))
}
if migErr == nil {
return preOut, preErr, nil
}
preErr = append(preErr, "dns-migrate: "+migErr.Error())
appendTraceLineRateLimited("transport", fmt.Sprintf("singbox dns migrate warning: client=%s err=%v", client.ID, migErr), 60*time.Second)
if transportSingBoxDNSMigrationStrict(client) {
res := transportBackendActionResult{
OK: false,
Code: "TRANSPORT_BACKEND_SINGBOX_DNS_MIGRATE_FAILED",
Message: migErr.Error(),
ExitCode: -1,
Stdout: strings.Join(preOut, "\n"),
Stderr: strings.Join(preErr, "\n"),
}
return preOut, preErr, &res
}
return preOut, preErr, nil
}