-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
103 lines (88 loc) · 2.74 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package main
import (
"fmt"
"log"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest/azure/cli"
"github.com/nlevee/aztunnel/internal/config"
"github.com/nlevee/aztunnel/internal/handler"
"github.com/nlevee/aztunnel/internal/ssh"
"github.com/nlevee/aztunnel/internal/tunnel"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
func init() {
pflag.StringP("config", "c", "", "Load config file")
pflag.Parse()
viper.BindPFlags(pflag.CommandLine)
}
func main() {
// read config file from disk
configFile := viper.GetString("config")
if configFile == "" {
log.Fatalf("-config flag is required")
}
cfg, err := config.LoadFromFile(configFile)
if err != nil {
log.Fatalf("cannot open config file: %v", err)
}
// Create a credential using the NewDefaultAzureCredential type.
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
log.Fatalf("failed to obtain a credential: %v", err)
}
// Establish a connection to the Key Vault client
privateKey, err := ssh.GetSSHPrivateKey(cred, cfg.Vault.Name, cfg.Vault.KeyPrefix)
if err != nil {
log.Fatalf("failed to obtain private Key: %v", err)
}
sshTunnelPort, _ := tunnel.GetFreePort()
// open tunnel to bastion
go func(port int, subID, rgName, bastion, bastionVM string) {
if subID == "" {
log.Fatalf("subscription id is required to start tunnel")
}
if rgName == "" {
log.Fatalf("resource-group is required to start tunnel")
}
cmd := cli.GetAzureCLICommand()
cmd.Args = append(cmd.Args, "network", "bastion", "tunnel",
fmt.Sprintf("--subscription=%s", subID),
fmt.Sprintf("--target-resource-id=/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/virtualMachines/%s", subID, rgName, bastionVM),
fmt.Sprintf("--port=%d", port),
fmt.Sprintf("--name=%s", bastion),
fmt.Sprintf("--resource-group=%s", rgName),
"--resource-port=22",
)
defer cmd.Process.Kill()
std, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("failed open tunnel: %v -- %s", err, std)
}
log.Printf("%s: %s", cmd.String(), std)
}(
sshTunnelPort,
cfg.SubscriptionID,
cfg.ResourceGroup,
cfg.Bastion.Name,
cfg.Bastion.Server,
)
config, err := ssh.GetSSHCliConfig(cfg.SSH.User, []byte(*privateKey.Value))
if err != nil {
log.Fatalf("cannot get ssh config for client: %v", err)
}
dest := cfg.SSH.Dest
if dest == "" {
log.Fatalf("destination server and port must be set")
}
kubeClusterName := cfg.Cluster
var kubeHandler handler.TunnelHandler
if kubeClusterName != "" {
kubeHandler = &handler.TunnelKubernetesHandler{
KubeClusterName: kubeClusterName,
}
}
if err := tunnel.RunTunnel(config, cfg.SSH.Port, sshTunnelPort, dest, kubeHandler); err != nil {
log.Fatalf("unable to run tunnel: %v", err)
}
}