-
Notifications
You must be signed in to change notification settings - Fork 0
/
swanctl.go
162 lines (134 loc) · 3.99 KB
/
swanctl.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package swanctl
import (
"context"
"fmt"
"os"
"strings"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fabedge/fabctl/pkg/types"
"github.com/fabedge/fabctl/pkg/util"
)
func New(clientGetter types.ClientGetter) *cobra.Command {
cmd := &cobra.Command{
Use: "swanctl [command] edge [flags]",
Short: "Execute swanctl command in strongswan containers",
Long: `Execute swanctl command in strongswan containers. There are four subcommands and you can also execute other swanctl subcommands`,
Example: `
fabctl swanctl list-conns edge1
To execute command on connectors, just input:
fabctl swanctl list-conns connector
To execute others swanctl commands, input like this:
fabctl swanctl edge1 -- --version
fabctl swanctl connector -- --version
`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
cli, err := clientGetter.GetClient()
util.CheckError(err)
execute(cli, args[0], args[1:]...)
},
}
cmd.AddCommand(newSubCommand(
"--list-conns",
clientGetter,
"list-conns edge [flags]",
"List loaded configurations of strongswan container in specified edge",
))
cmd.AddCommand(newSubCommand(
"--list-sa",
clientGetter,
"list-sa [edge] [flags]",
"List currently active IKE_SAs of strongswan container in specified edge",
))
cmd.AddCommand(newSubCommand(
"--initiate",
clientGetter,
"initiate edge [flags]",
"Initiate connection of strongswan container in specified edge",
addIKE, addChild, addTimeout,
))
cmd.AddCommand(newSubCommand(
"--terminate",
clientGetter,
"terminate edge [flags]",
"Terminate connection of strongswan container in specified edge",
addIKE, addChild, addTimeout,
))
return cmd
}
func newSubCommand(name string, clientGetter types.ClientGetter, usage, short string, funcs ...addFlagFunc) *cobra.Command {
sf := &swanctlFlags{}
cmd := &cobra.Command{
Use: usage,
Short: short,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
cli, err := clientGetter.GetClient()
util.CheckError(err)
execute(cli, args[0], sf.build(name)...)
},
}
addRawAndPretty(sf, cmd.Flags())
for _, addFlag := range funcs {
addFlag(sf, cmd.Flags())
}
return cmd
}
func execute(client *types.Client, edgeName string, flags ...string) {
if edgeName == "connector" {
executeOnConnectors(client, flags...)
return
}
podName := edgeName
// if edgeName has prefix like fabedge-connector or fabedge-agent, user may pass a pod name, just use it directly
if !strings.HasPrefix(edgeName, "fabedge-connector") && !strings.HasPrefix(edgeName, "fabedge-agent") {
podName = getAgentPodName(client, edgeName)
}
cmd := append([]string{"swanctl"}, flags...)
fmt.Printf("========================== %s =================================\n", podName)
err := client.Exec(podName, "strongswan", cmd)
util.CheckError(err)
}
//
func getAgentPodName(cli *types.Client, edgeName string) string {
agentName := fmt.Sprintf("fabedge-agent-%s", edgeName)
var (
pod corev1.Pod
key = types.ObjectKey{Name: agentName, Namespace: cli.GetNamespace()}
)
err := cli.Get(context.Background(), key, &pod)
if err == nil {
return pod.Name
}
if errors.IsNotFound(err) {
var podList corev1.PodList
err = cli.List(context.Background(), &podList,
client.InNamespace(cli.GetNamespace()),
client.MatchingLabels{
"fabedge.io/name": agentName,
})
util.CheckError(err)
if len(podList.Items) == 0 {
util.Exitf("no agent pod for node: %s", edgeName)
}
return podList.Items[0].Name
}
util.Exitf("failed to get agent pod: %s", err)
return ""
}
func executeOnConnectors(cli *types.Client, cmdFlags ...string) {
var pods corev1.PodList
err := cli.List(context.Background(), &pods, client.MatchingLabels{
"app": "fabedge-connector",
})
util.CheckError(err)
if len(pods.Items) == 0 {
fmt.Fprintln(os.Stderr, "no connectors found")
}
for _, pod := range pods.Items {
execute(cli, pod.Name, cmdFlags...)
}
}