1 package mapper
2
3 import (
4 "encoding/json"
5 "errors"
6 "fmt"
7
8 goVersion "github.com/hashicorp/go-version"
9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10
11 "edge-infra.dev/pkg/edge/api/graph/model"
12
13 v1ien "edge-infra.dev/pkg/sds/ien/k8s/apis/v1"
14 )
15
16 type metadata struct {
17 Name string `json:"name"`
18 Labels map[string]string `json:"labels"`
19 }
20 type resource struct {
21 Metadata metadata
22 }
23
24 func GenerateTerminalVersionMap(res []string) (map[string]map[string]string, error) {
25
26 versionMap := make(map[string]map[string]string)
27 for i := range res {
28 var resRow []string
29 err := json.Unmarshal([]byte(res[i]), &resRow)
30 if err != nil {
31 return nil, err
32 }
33
34 if len(resRow) < 2 {
35 return nil, errors.New("error getting terminal version")
36 }
37
38 var node resource
39 err = json.Unmarshal([]byte(resRow[0]), &node)
40 if err != nil {
41 return nil, err
42 }
43
44 edgeID := resRow[1]
45 hostname := node.Metadata.Name
46
47 if node.Metadata.Labels != nil {
48 version := node.Metadata.Labels["feature.node.kubernetes.io/ien-version"]
49 if versionMap[edgeID] == nil {
50 versionMap[edgeID] = make(map[string]string)
51 }
52 versionMap[edgeID][hostname] = version
53 }
54 }
55
56 return versionMap, nil
57 }
58
59 func TerminalToIENode(terminal *model.Terminal, clusterNetworkServices []*model.ClusterNetworkServiceInfo, customLabels map[string]string, edgeVersion string) v1ien.IENode {
60 return terminalToIENode(terminal, clusterNetworkServices, customLabels, edgeVersion)
61 }
62
63 func TerminalToCICIENode(terminal *model.Terminal, clusterNetworkServices []*model.ClusterNetworkServiceInfo, customLabels map[string]string, edgeVersion string) v1ien.IENode {
64 ien := terminalToIENode(terminal, clusterNetworkServices, customLabels, edgeVersion)
65
66
67 ien.ObjectMeta.Name = terminal.TerminalID
68
69
70
71 ien.Spec.ClusterEdgeID = terminal.ClusterEdgeID
72
73 ien.Spec.Hostname = terminal.Hostname
74
75 return ien
76 }
77
78 func terminalToIENode(terminal *model.Terminal, clusterNetworkServices []*model.ClusterNetworkServiceInfo, customLabels map[string]string, edgeVersion string) v1ien.IENode {
79
80 nodeNetwork := []v1ien.Network{}
81 for _, terminalInterface := range terminal.Interfaces {
82 network := TerminalInterfaceToNetwork(terminalInterface)
83 nodeNetwork = append(nodeNetwork, network)
84 }
85
86 terminalLane := ""
87 if terminal.Lane != nil {
88 terminalLane = *terminal.Lane
89 }
90
91 var terminalPrimaryInterface v1ien.PrimaryInterface
92
93 if terminal.PrimaryInterface == nil && len(terminal.Interfaces) != 0 {
94 terminalPrimaryInterface = v1ien.PrimaryInterface{
95 InterfaceID: terminal.Interfaces[0].TerminalInterfaceID,
96 MacAddresses: []string{terminal.Interfaces[0].MacAddress},
97 }
98 }
99
100 if terminal.PrimaryInterface != nil && len(*terminal.PrimaryInterface) != 0 {
101 terminalPrimaryInterface.InterfaceID = *terminal.PrimaryInterface
102 for _, itf := range terminal.Interfaces {
103 if itf.TerminalInterfaceID == *terminal.PrimaryInterface {
104 terminalPrimaryInterface.MacAddresses = append(terminalPrimaryInterface.MacAddresses, itf.MacAddress)
105 }
106 }
107 }
108
109
110 dnsServers, ntpServers, kubeVip := FilterNetworkServices(clusterNetworkServices)
111
112 node := v1ien.IENode{
113 TypeMeta: metav1.TypeMeta{
114 Kind: v1ien.IENodeGVK.Kind,
115 APIVersion: v1ien.IENodeGVK.GroupVersion().String(),
116 },
117 ObjectMeta: metav1.ObjectMeta{
118 Name: terminal.Hostname,
119 Labels: map[string]string{
120 "node.ncr.com/terminal-id": terminal.TerminalID,
121 },
122 },
123 Spec: v1ien.IENodeSpec{
124 Role: v1ien.Role(terminal.Role),
125 Lane: terminalLane,
126 Network: nodeNetwork,
127 PrimaryInterface: &terminalPrimaryInterface,
128 NetworkServices: v1ien.NetworkServices{
129 NTPServers: ntpServers,
130 DNSServers: dnsServers,
131 KubeVip: kubeVip,
132 },
133 SwapEnabled: &terminal.SwapEnabled,
134 CustomLabels: customLabels,
135 },
136 }
137
138
139 currentVersion, _ := goVersion.NewVersion(edgeVersion)
140
141
142 minimumVersion, _ := goVersion.NewVersion("v0.17.0")
143 if currentVersion != nil && currentVersion.LessThan(minimumVersion) {
144 node.Spec.PrimaryInterface = nil
145 }
146
147
148 minimumVersion, _ = goVersion.NewVersion("v0.18.0")
149 if currentVersion != nil && currentVersion.LessThan(minimumVersion) {
150 node.Spec.SwapEnabled = nil
151 }
152
153 if terminal.Class != nil {
154 node.Spec.Class = v1ien.Class(*terminal.Class)
155 }
156
157 return node
158 }
159
160 func TerminalInterfaceToNetwork(iface *model.TerminalInterface) v1ien.Network {
161 network := v1ien.Network{
162 DHCP4: iface.Dhcp4,
163 DHCP6: iface.Dhcp6,
164 MacAddress: iface.MacAddress,
165 }
166 if iface.Gateway4 != nil {
167 network.Gateway4 = *iface.Gateway4
168 }
169 if iface.Gateway6 != nil {
170 network.Gateway6 = *iface.Gateway6
171 }
172
173 addresses := []string{}
174 for _, address := range iface.Addresses {
175 if address.IP != nil {
176 nodeAddress := fmt.Sprintf("%s/%d", *address.IP, address.PrefixLen)
177 addresses = append(addresses, nodeAddress)
178 }
179 }
180 if len(addresses) > 0 {
181 network.Addresses = addresses
182 }
183 return network
184 }
185
186 func UnpackBannerTerminals(terminalMap map[string]*model.Terminal, ifaceMap map[string]*model.TerminalInterface, addressMap map[string]*model.TerminalAddress, versionMap map[string]map[string]string) []*model.Terminal {
187 terminals := []*model.Terminal{}
188
189 for _, address := range addressMap {
190 currIface := ifaceMap[address.TerminalInterfaceID]
191 currIface.Addresses = append(currIface.Addresses, address)
192 }
193 for _, iface := range ifaceMap {
194 currTerminal := terminalMap[iface.TerminalID]
195 currTerminal.Interfaces = append(currTerminal.Interfaces, iface)
196 }
197 for _, terminal := range terminalMap {
198 terminal.Version = versionMap[terminal.ClusterEdgeID][terminal.Hostname]
199 terminals = append(terminals, terminal)
200 }
201
202 return terminals
203 }
204
205
206 func FilterNetworkServices(clusterNetworkServices []*model.ClusterNetworkServiceInfo) ([]string, []string, string) {
207 dnsServers := []string{}
208 ntpServers := []string{}
209 vipAddress := ""
210
211 for _, service := range clusterNetworkServices {
212 switch service.ServiceType {
213 case "dns":
214 dnsServers = append(dnsServers, service.IP)
215 case "ntp":
216 ntpServers = append(ntpServers, service.IP)
217 case "kube-vip":
218 vipAddress = service.IP
219 }
220 }
221
222 return dnsServers, ntpServers, vipAddress
223 }
224
View as plain text