/
helper.go
145 lines (126 loc) · 3.48 KB
/
helper.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package cmd
import (
"fmt"
"net"
"os"
"os/user"
"path/filepath"
"strings"
"time"
"github.com/metal-stack/metal-go/api/models"
"github.com/metal-stack/metal-lib/auth"
"github.com/metal-stack/metalctl/pkg/api"
)
func parseNetworks(values []string) ([]*models.V1MachineAllocationNetwork, error) {
nets := []*models.V1MachineAllocationNetwork{}
for _, netWithFlag := range values {
id, autoAcquire, err := splitNetwork(netWithFlag)
if err != nil {
return nil, err
}
net := models.V1MachineAllocationNetwork{
Autoacquire: &autoAcquire,
Networkid: &id,
}
nets = append(nets, &net)
}
return nets, nil
}
func splitNetwork(value string) (string, bool, error) {
id, mode, found := strings.Cut(value, ":")
if !found {
return id, true, nil
}
switch strings.ToLower(mode) {
case "auto":
return id, true, nil
case "noauto":
return id, false, nil
default:
return "", false, fmt.Errorf("illegal mode: %s", mode)
}
}
const cloudContext = "cloudctl"
// getAuthContext reads AuthContext from given kubeconfig
func getAuthContext(kubeconfig string) (*auth.AuthContext, error) {
cs, err := api.GetContexts()
if err != nil {
return nil, err
}
authContext, err := auth.GetAuthContext(kubeconfig, formatContextName(cloudContext, cs.CurrentContext))
if err != nil {
return nil, err
}
if !authContext.AuthProviderOidc {
return nil, fmt.Errorf("active user %s has no oidc authProvider, check config", authContext.User)
}
return &authContext, nil
}
// formatContextName returns the contextName for the given suffix. suffix can be empty.
func formatContextName(prefix string, suffix string) string {
contextName := prefix
if suffix != "" {
contextName = fmt.Sprintf("%s-%s", cloudContext, suffix)
}
return contextName
}
func searchSSHKey() (string, error) {
currentUser, err := user.Current()
if err != nil {
return "", fmt.Errorf("unable to determine current user for expanding userdata path:%w", err)
}
homeDir := currentUser.HomeDir
defaultDir := filepath.Join(homeDir, "/.ssh/")
var key string
for _, k := range defaultSSHKeys {
possibleKey := filepath.Join(defaultDir, k)
_, err := os.ReadFile(possibleKey)
if err == nil {
fmt.Printf("using SSH identity: %s. Another identity can be specified with --sshidentity/-p\n",
possibleKey)
key = possibleKey
break
}
}
if key == "" {
return "", fmt.Errorf("failure to locate a SSH identity in default location (%s). "+
"Another identity can be specified with --sshidentity/-p\n", defaultDir)
}
return key, nil
}
func readFromFile(filePath string) (string, error) {
filePath, err := expandFilepath(filePath)
if err != nil {
return "", err
}
content, err := os.ReadFile(filePath)
if err != nil {
return "", fmt.Errorf("unable to read from given file %s error:%w", filePath, err)
}
return strings.TrimSpace(string(content)), nil
}
func expandFilepath(filePath string) (string, error) {
currentUser, err := user.Current()
if err != nil {
return "", fmt.Errorf("unable to determine current user for expanding userdata path:%w", err)
}
homeDir := currentUser.HomeDir
if filePath == "~" {
filePath = homeDir
} else if strings.HasPrefix(filePath, "~/") {
filePath = filepath.Join(homeDir, filePath[2:])
}
return filePath, nil
}
func portOpen(ip string, port string, timeout time.Duration) bool {
address := net.JoinHostPort(ip, port)
conn, err := net.DialTimeout("tcp", address, timeout)
if err != nil {
return false
}
if conn != nil {
_ = conn.Close()
return true
}
return false
}