blob: 09f409700616a3b36132cf7aecba88106845610c [file] [log] [blame]
Jian Li49109b52019-01-22 00:17:28 +09001/*
2 * Copyright 2019-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.k8snode.api;
17
18import com.google.common.base.MoreObjects;
Jian Lie2a04ce2020-07-01 19:07:02 +090019import org.apache.commons.lang.StringUtils;
Jian Li49109b52019-01-22 00:17:28 +090020import org.onlab.osgi.DefaultServiceDirectory;
21import org.onlab.packet.IpAddress;
Jian Li7d111d72019-04-12 13:58:44 +090022import org.onlab.packet.MacAddress;
Jian Lie2a04ce2020-07-01 19:07:02 +090023import org.onosproject.k8snode.api.K8sApiConfig.Mode;
Jian Li2778ffa2019-05-07 13:21:52 +090024import org.onosproject.net.Annotations;
Jian Li49109b52019-01-22 00:17:28 +090025import org.onosproject.net.DeviceId;
26import org.onosproject.net.Port;
27import org.onosproject.net.PortNumber;
28import org.onosproject.net.device.DeviceService;
29
30import java.util.Objects;
Jian Lie2a04ce2020-07-01 19:07:02 +090031import java.util.UUID;
Jian Li49109b52019-01-22 00:17:28 +090032
33import static com.google.common.base.Preconditions.checkArgument;
Jian Lie2a04ce2020-07-01 19:07:02 +090034import static org.onosproject.k8snode.api.Constants.DEFAULT_CLUSTER_NAME;
Jian Lic2242bd2020-09-03 13:12:14 +090035import static org.onosproject.k8snode.api.Constants.DEFAULT_EXTERNAL_BRIDGE_MAC;
36import static org.onosproject.k8snode.api.Constants.DEFAULT_EXTERNAL_GATEWAY_MAC;
Jian Li019ce6a2020-09-09 10:23:21 +090037import static org.onosproject.k8snode.api.Constants.DEFAULT_INTG_BRIDGE_MAC;
Jian Lieb488ea2019-04-16 01:50:02 +090038import static org.onosproject.k8snode.api.Constants.EXTERNAL_BRIDGE;
Jian Li019ce6a2020-09-09 10:23:21 +090039import static org.onosproject.k8snode.api.Constants.EXTERNAL_TO_ROUTER;
Jian Li49109b52019-01-22 00:17:28 +090040import static org.onosproject.k8snode.api.Constants.GENEVE_TUNNEL;
41import static org.onosproject.k8snode.api.Constants.GRE_TUNNEL;
Jian Li4aa17642019-01-30 00:01:11 +090042import static org.onosproject.k8snode.api.Constants.INTEGRATION_BRIDGE;
Jian Lieb488ea2019-04-16 01:50:02 +090043import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_EXTERNAL_BRIDGE;
Jian Li1a2eb5d2019-08-27 02:07:05 +090044import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_LOCAL_BRIDGE;
Jian Lie2a04ce2020-07-01 19:07:02 +090045import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_TUN_BRIDGE;
Jian Li019ce6a2020-09-09 10:23:21 +090046import static org.onosproject.k8snode.api.Constants.K8S_TO_OS_BRIDGE;
Jian Lie2a04ce2020-07-01 19:07:02 +090047import static org.onosproject.k8snode.api.Constants.LOCAL_BRIDGE;
Jian Li1a2eb5d2019-08-27 02:07:05 +090048import static org.onosproject.k8snode.api.Constants.LOCAL_TO_INTEGRATION_BRIDGE;
Jian Li019ce6a2020-09-09 10:23:21 +090049import static org.onosproject.k8snode.api.Constants.OS_TO_K8S_BRIDGE;
Jian Lieb488ea2019-04-16 01:50:02 +090050import static org.onosproject.k8snode.api.Constants.PHYSICAL_EXTERNAL_BRIDGE;
Jian Li019ce6a2020-09-09 10:23:21 +090051import static org.onosproject.k8snode.api.Constants.ROUTER;
52import static org.onosproject.k8snode.api.Constants.ROUTER_TO_EXTERNAL;
Jian Lie2a04ce2020-07-01 19:07:02 +090053import static org.onosproject.k8snode.api.Constants.TUNNEL_BRIDGE;
54import static org.onosproject.k8snode.api.Constants.TUN_TO_INTEGRATION_BRIDGE;
Jian Li49109b52019-01-22 00:17:28 +090055import static org.onosproject.k8snode.api.Constants.VXLAN_TUNNEL;
Jian Lie2a04ce2020-07-01 19:07:02 +090056import static org.onosproject.k8snode.api.K8sApiConfig.Mode.NORMAL;
57import static org.onosproject.k8snode.api.K8sApiConfig.Mode.PASSTHROUGH;
Jian Li49109b52019-01-22 00:17:28 +090058import static org.onosproject.net.AnnotationKeys.PORT_NAME;
59
60/**
61 * Representation of a kubernetes node.
62 */
63public class DefaultK8sNode implements K8sNode {
64
Jian Li2778ffa2019-05-07 13:21:52 +090065 private static final String PORT_MAC = "portMac";
Jian Lie2a04ce2020-07-01 19:07:02 +090066 private static final String FLOW_KEY = "flow";
Jian Li7d111d72019-04-12 13:58:44 +090067
Jian Lie2a04ce2020-07-01 19:07:02 +090068 private static final int SHORT_NAME_LENGTH = 10;
69
70 private final String clusterName;
Jian Li49109b52019-01-22 00:17:28 +090071 private final String hostname;
72 private final Type type;
Jian Lie2a04ce2020-07-01 19:07:02 +090073 private final int segmentId;
74 private final Mode mode;
Jian Li49109b52019-01-22 00:17:28 +090075 private final DeviceId intgBridge;
Jian Libf562c22019-04-15 18:07:14 +090076 private final DeviceId extBridge;
Jian Li1a2eb5d2019-08-27 02:07:05 +090077 private final DeviceId localBridge;
Jian Lie2a04ce2020-07-01 19:07:02 +090078 private final DeviceId tunBridge;
Jian Li49109b52019-01-22 00:17:28 +090079 private final IpAddress managementIp;
80 private final IpAddress dataIp;
81 private final K8sNodeState state;
Jian Li0c632722019-05-08 15:58:04 +090082 private final String extIntf;
Jian Lie2a04ce2020-07-01 19:07:02 +090083 private final K8sExternalNetwork extNetwork;
Jian Li0c632722019-05-08 15:58:04 +090084 private final String podCidr;
Jian Li49109b52019-01-22 00:17:28 +090085
86 private static final String NOT_NULL_MSG = "Node % cannot be null";
87
88 private static final String OVSDB = "ovsdb:";
89
90 /**
91 * A default constructor of kubernetes Node.
92 *
Jian Lie2a04ce2020-07-01 19:07:02 +090093 * @param clusterName clusterName
Jian Li49109b52019-01-22 00:17:28 +090094 * @param hostname hostname
95 * @param type node type
Jian Lie2a04ce2020-07-01 19:07:02 +090096 * @param segmentId segment identifier
97 * @param mode CNI running mode
Jian Li49109b52019-01-22 00:17:28 +090098 * @param intgBridge integration bridge
Jian Libf562c22019-04-15 18:07:14 +090099 * @param extBridge external bridge
Jian Li1a2eb5d2019-08-27 02:07:05 +0900100 * @param localBridge local bridge
Jian Lie2a04ce2020-07-01 19:07:02 +0900101 * @param tunBridge tunnel bridge
Jian Li0c632722019-05-08 15:58:04 +0900102 * @param extIntf external interface
Jian Li49109b52019-01-22 00:17:28 +0900103 * @param managementIp management IP address
104 * @param dataIp data IP address
105 * @param state node state
Jian Lie2a04ce2020-07-01 19:07:02 +0900106 * @param extNetwork external network
Jian Li0c632722019-05-08 15:58:04 +0900107 * @param podCidr POD CIDR
Jian Li49109b52019-01-22 00:17:28 +0900108 */
Jian Lie2a04ce2020-07-01 19:07:02 +0900109 protected DefaultK8sNode(String clusterName, String hostname, Type type,
110 int segmentId, Mode mode, DeviceId intgBridge,
Jian Li1a2eb5d2019-08-27 02:07:05 +0900111 DeviceId extBridge, DeviceId localBridge,
Jian Lie2a04ce2020-07-01 19:07:02 +0900112 DeviceId tunBridge, String extIntf, IpAddress managementIp,
Jian Li1a2eb5d2019-08-27 02:07:05 +0900113 IpAddress dataIp, K8sNodeState state,
Jian Lie2a04ce2020-07-01 19:07:02 +0900114 K8sExternalNetwork extNetwork, String podCidr) {
115 this.clusterName = clusterName;
Jian Li49109b52019-01-22 00:17:28 +0900116 this.hostname = hostname;
117 this.type = type;
Jian Lie2a04ce2020-07-01 19:07:02 +0900118 this.mode = mode;
119 this.segmentId = segmentId;
Jian Li49109b52019-01-22 00:17:28 +0900120 this.intgBridge = intgBridge;
Jian Libf562c22019-04-15 18:07:14 +0900121 this.extBridge = extBridge;
Jian Li1a2eb5d2019-08-27 02:07:05 +0900122 this.localBridge = localBridge;
Jian Lie2a04ce2020-07-01 19:07:02 +0900123 this.tunBridge = tunBridge;
Jian Li0c632722019-05-08 15:58:04 +0900124 this.extIntf = extIntf;
Jian Li49109b52019-01-22 00:17:28 +0900125 this.managementIp = managementIp;
126 this.dataIp = dataIp;
127 this.state = state;
Jian Lie2a04ce2020-07-01 19:07:02 +0900128 this.extNetwork = extNetwork;
Jian Li0c632722019-05-08 15:58:04 +0900129 this.podCidr = podCidr;
Jian Li49109b52019-01-22 00:17:28 +0900130 }
131
132 @Override
Jian Lie2a04ce2020-07-01 19:07:02 +0900133 public String clusterName() {
134 return clusterName;
135 }
136
137 @Override
138 public String hostShortName() {
139 return StringUtils.substring(hostname, 0, SHORT_NAME_LENGTH);
140 }
141
142 @Override
143 public String uniqueString(int length) {
144 String uuid = UUID.nameUUIDFromBytes(hostname.getBytes()).toString();
145 return StringUtils.substring(uuid, 0, length);
146 }
147
148 @Override
149 public int segmentId() {
150 return segmentId;
151 }
152
153 @Override
154 public String tunnelKey() {
155 if (mode == PASSTHROUGH) {
156 return String.valueOf(segmentId);
157 } else {
158 return FLOW_KEY;
159 }
160 }
161
162 @Override
163 public Mode mode() {
164 return mode;
165 }
166
167 @Override
Jian Li49109b52019-01-22 00:17:28 +0900168 public String hostname() {
169 return hostname;
170 }
171
172 @Override
173 public Type type() {
174 return type;
175 }
176
177 @Override
178 public DeviceId ovsdb() {
179 return DeviceId.deviceId(OVSDB + managementIp().toString());
180 }
181
182 @Override
183 public DeviceId intgBridge() {
184 return intgBridge;
185 }
186
187 @Override
Jian Libf562c22019-04-15 18:07:14 +0900188 public DeviceId extBridge() {
189 return extBridge;
190 }
191
192 @Override
Jian Li1a2eb5d2019-08-27 02:07:05 +0900193 public DeviceId localBridge() {
194 return localBridge;
195 }
196
197 @Override
Jian Lie2a04ce2020-07-01 19:07:02 +0900198 public DeviceId tunBridge() {
Jian Li732c3422020-09-07 17:01:11 +0900199
200 if (mode == PASSTHROUGH) {
201 K8sHostService hostService =
202 DefaultServiceDirectory.getService(K8sHostService.class);
203 DeviceId deviceId = null;
204 for (K8sHost host : hostService.hosts()) {
205 if (host.nodeNames().contains(hostname())) {
206 for (K8sTunnelBridge bridge : host.tunBridges()) {
207 if (bridge.tunnelId() == segmentId()) {
208 deviceId = bridge.deviceId();
209 }
210 }
211 }
212 }
213 return deviceId;
214 } else {
215 return tunBridge;
216 }
Jian Lie2a04ce2020-07-01 19:07:02 +0900217 }
218
219 @Override
Jian Li0c632722019-05-08 15:58:04 +0900220 public String extIntf() {
221 return extIntf;
222 }
223
224 @Override
Jian Li1cee9882019-02-13 11:25:25 +0900225 public K8sNode updateIntgBridge(DeviceId deviceId) {
226 return new Builder()
227 .hostname(hostname)
Jian Lie2a04ce2020-07-01 19:07:02 +0900228 .clusterName(clusterName)
Jian Li1cee9882019-02-13 11:25:25 +0900229 .type(type)
Jian Lie2a04ce2020-07-01 19:07:02 +0900230 .segmentId(segmentId)
231 .mode(mode)
Jian Li1cee9882019-02-13 11:25:25 +0900232 .intgBridge(deviceId)
Jian Libf562c22019-04-15 18:07:14 +0900233 .extBridge(extBridge)
Jian Li1a2eb5d2019-08-27 02:07:05 +0900234 .localBridge(localBridge)
Jian Lie2a04ce2020-07-01 19:07:02 +0900235 .tunBridge(tunBridge)
Jian Li0c632722019-05-08 15:58:04 +0900236 .extIntf(extIntf)
Jian Libf562c22019-04-15 18:07:14 +0900237 .managementIp(managementIp)
238 .dataIp(dataIp)
239 .state(state)
Jian Lie2a04ce2020-07-01 19:07:02 +0900240 .extBridgeIp(extNetwork.extBridgeIp())
241 .extGatewayIp(extNetwork.extGatewayIp())
242 .extGatewayMac(extNetwork.extGatewayMac())
Jian Li0c632722019-05-08 15:58:04 +0900243 .podCidr(podCidr)
Jian Libf562c22019-04-15 18:07:14 +0900244 .build();
245 }
246
247 @Override
248 public K8sNode updateExtBridge(DeviceId deviceId) {
249 return new Builder()
250 .hostname(hostname)
Jian Lie2a04ce2020-07-01 19:07:02 +0900251 .clusterName(clusterName)
Jian Libf562c22019-04-15 18:07:14 +0900252 .type(type)
Jian Lie2a04ce2020-07-01 19:07:02 +0900253 .segmentId(segmentId)
254 .mode(mode)
Jian Libf562c22019-04-15 18:07:14 +0900255 .intgBridge(intgBridge)
256 .extBridge(deviceId)
Jian Li1a2eb5d2019-08-27 02:07:05 +0900257 .localBridge(localBridge)
Jian Lie2a04ce2020-07-01 19:07:02 +0900258 .tunBridge(tunBridge)
Jian Li1a2eb5d2019-08-27 02:07:05 +0900259 .extIntf(extIntf)
260 .managementIp(managementIp)
261 .dataIp(dataIp)
262 .state(state)
Jian Lie2a04ce2020-07-01 19:07:02 +0900263 .extBridgeIp(extNetwork.extBridgeIp())
264 .extGatewayIp(extNetwork.extGatewayIp())
265 .extGatewayMac(extNetwork.extGatewayMac())
Jian Li1a2eb5d2019-08-27 02:07:05 +0900266 .podCidr(podCidr)
267 .build();
268 }
269
270 @Override
271 public K8sNode updateLocalBridge(DeviceId deviceId) {
272 return new Builder()
273 .hostname(hostname)
Jian Lie2a04ce2020-07-01 19:07:02 +0900274 .clusterName(clusterName)
Jian Li1a2eb5d2019-08-27 02:07:05 +0900275 .type(type)
Jian Lie2a04ce2020-07-01 19:07:02 +0900276 .segmentId(segmentId)
277 .mode(mode)
Jian Li1a2eb5d2019-08-27 02:07:05 +0900278 .intgBridge(intgBridge)
279 .extBridge(extBridge)
280 .localBridge(deviceId)
Jian Lie2a04ce2020-07-01 19:07:02 +0900281 .tunBridge(tunBridge)
Jian Li0c632722019-05-08 15:58:04 +0900282 .extIntf(extIntf)
Jian Li1cee9882019-02-13 11:25:25 +0900283 .managementIp(managementIp)
284 .dataIp(dataIp)
285 .state(state)
Jian Lie2a04ce2020-07-01 19:07:02 +0900286 .extBridgeIp(extNetwork.extBridgeIp())
287 .extGatewayIp(extNetwork.extGatewayIp())
288 .extGatewayMac(extNetwork.extGatewayMac())
289 .podCidr(podCidr)
290 .build();
291 }
292
293 @Override
294 public K8sNode updateTunBridge(DeviceId deviceId) {
295 return new Builder()
296 .hostname(hostname)
297 .clusterName(clusterName)
298 .type(type)
299 .segmentId(segmentId)
300 .mode(mode)
301 .intgBridge(intgBridge)
302 .extBridge(extBridge)
303 .localBridge(localBridge)
304 .tunBridge(deviceId)
305 .extIntf(extIntf)
306 .managementIp(managementIp)
307 .dataIp(dataIp)
308 .state(state)
309 .extBridgeIp(extNetwork.extBridgeIp())
310 .extGatewayIp(extNetwork.extGatewayIp())
311 .extGatewayMac(extNetwork.extGatewayMac())
Jian Li0c632722019-05-08 15:58:04 +0900312 .podCidr(podCidr)
Jian Li1cee9882019-02-13 11:25:25 +0900313 .build();
314 }
315
316 @Override
Jian Li49109b52019-01-22 00:17:28 +0900317 public IpAddress managementIp() {
318 return managementIp;
319 }
320
321 @Override
322 public IpAddress dataIp() {
323 return dataIp;
324 }
325
326 @Override
327 public K8sNodeState state() {
328 return state;
329 }
330
331 @Override
Jian Li0c632722019-05-08 15:58:04 +0900332 public String podCidr() {
333 return podCidr;
334 }
335
336 @Override
Jian Li49109b52019-01-22 00:17:28 +0900337 public K8sNode updateState(K8sNodeState newState) {
338 return new Builder()
339 .hostname(hostname)
Jian Lie2a04ce2020-07-01 19:07:02 +0900340 .clusterName(clusterName)
Jian Li49109b52019-01-22 00:17:28 +0900341 .type(type)
Jian Lie2a04ce2020-07-01 19:07:02 +0900342 .segmentId(segmentId)
343 .mode(mode)
Jian Li49109b52019-01-22 00:17:28 +0900344 .intgBridge(intgBridge)
Jian Li0c632722019-05-08 15:58:04 +0900345 .extBridge(extBridge)
Jian Li1a2eb5d2019-08-27 02:07:05 +0900346 .localBridge(localBridge)
Jian Lie2a04ce2020-07-01 19:07:02 +0900347 .tunBridge(tunBridge)
Jian Li0c632722019-05-08 15:58:04 +0900348 .extIntf(extIntf)
Jian Li49109b52019-01-22 00:17:28 +0900349 .managementIp(managementIp)
350 .dataIp(dataIp)
351 .state(newState)
Jian Lie2a04ce2020-07-01 19:07:02 +0900352 .extBridgeIp(extNetwork.extBridgeIp())
353 .extGatewayIp(extNetwork.extGatewayIp())
354 .extGatewayMac(extNetwork.extGatewayMac())
Jian Li0c632722019-05-08 15:58:04 +0900355 .podCidr(podCidr)
Jian Li49109b52019-01-22 00:17:28 +0900356 .build();
357 }
358
359 @Override
Jian Li1b08d652019-05-02 17:28:09 +0900360 public K8sNode updateExtGatewayMac(MacAddress newMac) {
361 return new Builder()
362 .hostname(hostname)
Jian Lie2a04ce2020-07-01 19:07:02 +0900363 .clusterName(clusterName)
Jian Li1b08d652019-05-02 17:28:09 +0900364 .type(type)
Jian Lie2a04ce2020-07-01 19:07:02 +0900365 .segmentId(segmentId)
366 .mode(mode)
Jian Li1b08d652019-05-02 17:28:09 +0900367 .intgBridge(intgBridge)
Jian Li0c632722019-05-08 15:58:04 +0900368 .extBridge(extBridge)
Jian Li1a2eb5d2019-08-27 02:07:05 +0900369 .localBridge(localBridge)
Jian Lie2a04ce2020-07-01 19:07:02 +0900370 .tunBridge(tunBridge)
Jian Li0c632722019-05-08 15:58:04 +0900371 .extIntf(extIntf)
Jian Li1b08d652019-05-02 17:28:09 +0900372 .managementIp(managementIp)
373 .dataIp(dataIp)
374 .state(state)
Jian Lie2a04ce2020-07-01 19:07:02 +0900375 .extBridgeIp(extNetwork.extBridgeIp())
376 .extGatewayIp(extNetwork.extGatewayIp())
Jian Li1b08d652019-05-02 17:28:09 +0900377 .extGatewayMac(newMac)
Jian Li0c632722019-05-08 15:58:04 +0900378 .podCidr(podCidr)
Jian Li1b08d652019-05-02 17:28:09 +0900379 .build();
Jian Li1b08d652019-05-02 17:28:09 +0900380 }
381
382 @Override
Jian Li49109b52019-01-22 00:17:28 +0900383 public PortNumber grePortNum() {
Jian Lie2a04ce2020-07-01 19:07:02 +0900384 return tunnelPortNum(grePortName());
Jian Li49109b52019-01-22 00:17:28 +0900385 }
386
387 @Override
388 public PortNumber vxlanPortNum() {
Jian Lie2a04ce2020-07-01 19:07:02 +0900389 return tunnelPortNum(vxlanPortName());
Jian Li49109b52019-01-22 00:17:28 +0900390 }
391
392 @Override
393 public PortNumber genevePortNum() {
Jian Lie2a04ce2020-07-01 19:07:02 +0900394 return tunnelPortNum(genevePortName());
Jian Li49109b52019-01-22 00:17:28 +0900395 }
396
397 @Override
Jian Lieb488ea2019-04-16 01:50:02 +0900398 public PortNumber intgBridgePortNum() {
Jian Li5abc9f02020-09-04 19:38:37 +0900399 return PortNumber.LOCAL;
Jian Lieb488ea2019-04-16 01:50:02 +0900400 }
401
402 @Override
403 public PortNumber intgToExtPatchPortNum() {
Jian Lie2a04ce2020-07-01 19:07:02 +0900404 return portNumber(intgBridge, intgToExtPatchPortName());
Jian Lieb488ea2019-04-16 01:50:02 +0900405 }
406
407 @Override
Jian Li1a2eb5d2019-08-27 02:07:05 +0900408 public PortNumber intgToLocalPatchPortNum() {
Jian Lie2a04ce2020-07-01 19:07:02 +0900409 return portNumber(intgBridge, intgToLocalPatchPortName());
Jian Li1a2eb5d2019-08-27 02:07:05 +0900410 }
411
412 @Override
Jian Lie2a04ce2020-07-01 19:07:02 +0900413 public PortNumber localToIntgPatchPortNum() {
414 return portNumber(localBridge, localToIntgPatchPortName());
Jian Li1a2eb5d2019-08-27 02:07:05 +0900415 }
416
417 @Override
Jian Lieb488ea2019-04-16 01:50:02 +0900418 public PortNumber extToIntgPatchPortNum() {
Jian Lie2a04ce2020-07-01 19:07:02 +0900419 return portNumber(extBridge, extToIntgPatchPortName());
Jian Lieb488ea2019-04-16 01:50:02 +0900420 }
421
422 @Override
Jian Li619fa282020-09-02 14:45:35 +0900423 public PortNumber intgToTunPortNum() {
424 return portNumber(intgBridge, intgToTunPatchPortName());
425 }
426
427 @Override
428 public PortNumber tunToIntgPortNum() {
Jian Li732c3422020-09-07 17:01:11 +0900429 if (mode() == PASSTHROUGH) {
430 K8sHostService hostService =
431 DefaultServiceDirectory.getService(K8sHostService.class);
432 Port port = null;
433 for (K8sHost host : hostService.hosts()) {
434 if (host.nodeNames().contains(hostname())) {
435 for (K8sTunnelBridge bridge : host.tunBridges()) {
436 if (bridge.tunnelId() == segmentId()) {
437 port = port(bridge.deviceId(), tunToIntgPatchPortName());
438 }
439 }
440 }
441 }
442
443 if (port == null) {
444 return null;
445 } else {
446 return port.number();
447 }
448 } else {
449 return portNumber(tunBridge, tunToIntgPatchPortName());
450 }
Jian Li619fa282020-09-02 14:45:35 +0900451 }
452
453 @Override
Jian Li019ce6a2020-09-09 10:23:21 +0900454 public PortNumber routerToExtPortNum() {
455 if (mode() == PASSTHROUGH) {
456 K8sHostService hostService =
457 DefaultServiceDirectory.getService(K8sHostService.class);
458 Port port = null;
459 for (K8sHost host : hostService.hosts()) {
460 if (host.nodeNames().contains(hostname())) {
461 for (K8sRouterBridge bridge : host.routerBridges()) {
462 if (bridge.segmentId() == segmentId()) {
463 port = port(bridge.deviceId(), routerToExtPatchPortName());
464 }
465 }
466 }
467 }
468
469 if (port == null) {
470 return null;
471 } else {
472 return port.number();
473 }
474 }
475
476 return null;
477 }
478
479 @Override
480 public PortNumber extToRouterPortNum() {
481 return portNumber(extBridge, extToRouterPatchPortName());
482 }
483
484 @Override
485 public PortNumber routerPortNum() {
486 if (mode() == PASSTHROUGH) {
487 K8sHostService hostService =
488 DefaultServiceDirectory.getService(K8sHostService.class);
489 Port port = null;
490 for (K8sHost host : hostService.hosts()) {
491 if (host.nodeNames().contains(hostname())) {
492 for (K8sRouterBridge bridge : host.routerBridges()) {
493 if (bridge.segmentId() == segmentId()) {
494 port = port(bridge.deviceId(), routerPortName());
495 }
496 }
497 }
498 }
499
500 if (port == null) {
501 return null;
502 } else {
503 return port.number();
504 }
505 }
506
507 return null;
508 }
509
510 @Override
Jian Lieb488ea2019-04-16 01:50:02 +0900511 public PortNumber extBridgePortNum() {
Jian Li5abc9f02020-09-04 19:38:37 +0900512 return PortNumber.LOCAL;
Jian Lieb488ea2019-04-16 01:50:02 +0900513 }
514
515 @Override
Jian Lic2242bd2020-09-03 13:12:14 +0900516 public PortNumber extIntfPortNum() {
517 if (this.extIntf == null) {
518 return null;
519 }
520 return portNumber(extBridge, extIntf());
521 }
522
523 @Override
Jian Li2778ffa2019-05-07 13:21:52 +0900524 public MacAddress intgBridgeMac() {
Jian Li019ce6a2020-09-09 10:23:21 +0900525 if (mode == PASSTHROUGH) {
526 return MacAddress.valueOf(DEFAULT_INTG_BRIDGE_MAC);
527 } else {
528 return macAddress(intgBridge, intgBridgeName());
529 }
Jian Li2778ffa2019-05-07 13:21:52 +0900530 }
531
532 @Override
533 public IpAddress extBridgeIp() {
Jian Lie2a04ce2020-07-01 19:07:02 +0900534 return extNetwork.extBridgeIp();
Jian Li2778ffa2019-05-07 13:21:52 +0900535 }
536
537 @Override
538 public MacAddress extBridgeMac() {
Jian Lic2242bd2020-09-03 13:12:14 +0900539 if (MacAddress.valueOf(DEFAULT_EXTERNAL_GATEWAY_MAC).equals(extGatewayMac())) {
540 return MacAddress.valueOf(DEFAULT_EXTERNAL_BRIDGE_MAC);
541 } else {
542 return macAddress(extBridge, extBridgeName());
543 }
Jian Li2778ffa2019-05-07 13:21:52 +0900544 }
545
546 @Override
547 public IpAddress extGatewayIp() {
Jian Lie2a04ce2020-07-01 19:07:02 +0900548 return extNetwork.extGatewayIp();
Jian Li2778ffa2019-05-07 13:21:52 +0900549 }
550
551 @Override
552 public MacAddress extGatewayMac() {
Jian Lie2a04ce2020-07-01 19:07:02 +0900553 return extNetwork.extGatewayMac();
554 }
555
556 @Override
557 public String grePortName() {
558 if (mode == PASSTHROUGH) {
559 return GRE_TUNNEL + "-" + segmentId;
560 } else {
561 return GRE_TUNNEL;
562 }
563 }
564
565 @Override
566 public String vxlanPortName() {
567 if (mode == PASSTHROUGH) {
568 return VXLAN_TUNNEL + "-" + segmentId;
569 } else {
570 return VXLAN_TUNNEL;
571 }
572 }
573
574 @Override
575 public String genevePortName() {
576 if (mode == PASSTHROUGH) {
577 return GENEVE_TUNNEL + "-" + segmentId;
578 } else {
579 return GENEVE_TUNNEL;
580 }
581 }
582
583 @Override
584 public String intgBridgeName() {
585 if (mode == PASSTHROUGH) {
586 return INTEGRATION_BRIDGE + "-" + uniqueString(5);
587 } else {
588 return INTEGRATION_BRIDGE;
589 }
590 }
591
592 @Override
Jian Li019ce6a2020-09-09 10:23:21 +0900593 public String intgEntryPortName() {
594 if (mode == PASSTHROUGH) {
595 return k8sToOsIntgPatchPortName();
596 } else {
597 return intgBridgeName();
598 }
599 }
600
601 @Override
602 public PortNumber intgEntryPortNum() {
603 if (mode == PASSTHROUGH) {
604 return portNumber(intgBridge, k8sToOsIntgPatchPortName());
605 } else {
606 return intgBridgePortNum();
607 }
608 }
609
610 @Override
Jian Lie2a04ce2020-07-01 19:07:02 +0900611 public String extBridgeName() {
612 if (mode == PASSTHROUGH) {
613 return EXTERNAL_BRIDGE + "-" + uniqueString(5);
614 } else {
615 return EXTERNAL_BRIDGE;
616 }
617 }
618
619 @Override
620 public String localBridgeName() {
621 if (mode == PASSTHROUGH) {
622 return LOCAL_BRIDGE + "-" + uniqueString(5);
623 } else {
624 return LOCAL_BRIDGE;
625 }
626 }
627
628 @Override
629 public String tunBridgeName() {
630 if (mode == PASSTHROUGH) {
631 return TUNNEL_BRIDGE + "-" + segmentId;
632 } else {
633 return TUNNEL_BRIDGE;
634 }
635 }
636
637 @Override
638 public String intgBridgePortName() {
639 if (mode == PASSTHROUGH) {
640 return INTEGRATION_BRIDGE + "-" + uniqueString(5);
641 } else {
642 return INTEGRATION_BRIDGE;
643 }
644 }
645
646 @Override
647 public String extBridgePortName() {
648 if (mode == PASSTHROUGH) {
649 return EXTERNAL_BRIDGE + "-" + uniqueString(5);
650 } else {
651 return EXTERNAL_BRIDGE;
652 }
653 }
654
655 @Override
656 public String localBridgePortName() {
657 if (mode == PASSTHROUGH) {
658 return LOCAL_BRIDGE + "-" + uniqueString(5);
659 } else {
660 return LOCAL_BRIDGE;
661 }
662 }
663
664 @Override
Jian Li619fa282020-09-02 14:45:35 +0900665 public String tunBridgePortName() {
666 if (mode == PASSTHROUGH) {
667 return TUNNEL_BRIDGE + "-" + uniqueString(5);
668 } else {
669 return TUNNEL_BRIDGE;
670 }
671 }
672
673 @Override
Jian Lie2a04ce2020-07-01 19:07:02 +0900674 public String intgToExtPatchPortName() {
675 if (mode == PASSTHROUGH) {
676 return INTEGRATION_TO_EXTERNAL_BRIDGE + "-" + uniqueString(5);
677 } else {
678 return INTEGRATION_TO_EXTERNAL_BRIDGE;
679 }
680 }
681
682 @Override
683 public String intgToTunPatchPortName() {
684 if (mode == PASSTHROUGH) {
685 return INTEGRATION_TO_TUN_BRIDGE + "-" + uniqueString(5);
686 } else {
687 return INTEGRATION_TO_TUN_BRIDGE;
688 }
689 }
690
691 @Override
692 public String intgToLocalPatchPortName() {
693 if (mode == PASSTHROUGH) {
694 return INTEGRATION_TO_LOCAL_BRIDGE + "-" + uniqueString(5);
695 } else {
696 return INTEGRATION_TO_LOCAL_BRIDGE;
697 }
698 }
699
700 @Override
701 public String localToIntgPatchPortName() {
702 if (mode == PASSTHROUGH) {
703 return LOCAL_TO_INTEGRATION_BRIDGE + "-" + uniqueString(5);
704 } else {
705 return LOCAL_TO_INTEGRATION_BRIDGE;
706 }
707 }
708
709 @Override
710 public String extToIntgPatchPortName() {
711 if (mode == PASSTHROUGH) {
712 return PHYSICAL_EXTERNAL_BRIDGE + "-" + uniqueString(5);
713 } else {
714 return PHYSICAL_EXTERNAL_BRIDGE;
715 }
716 }
717
718 @Override
719 public String tunToIntgPatchPortName() {
720 if (mode == PASSTHROUGH) {
721 return TUN_TO_INTEGRATION_BRIDGE + "-" + uniqueString(5);
722 } else {
723 return TUN_TO_INTEGRATION_BRIDGE;
724 }
Jian Li2778ffa2019-05-07 13:21:52 +0900725 }
726
727 @Override
Jian Li019ce6a2020-09-09 10:23:21 +0900728 public String k8sToOsIntgPatchPortName() {
729 if (mode == PASSTHROUGH) {
730 return K8S_TO_OS_BRIDGE + "-" + uniqueString(5);
731 } else {
732 return K8S_TO_OS_BRIDGE;
733 }
734 }
735
736 @Override
737 public String osToK8sIntgPatchPortName() {
738 if (mode == PASSTHROUGH) {
739 return OS_TO_K8S_BRIDGE + "-" + uniqueString(5);
740 } else {
741 return OS_TO_K8S_BRIDGE;
742 }
743 }
744
745 @Override
746 public String routerToExtPatchPortName() {
747 if (mode == PASSTHROUGH) {
748 return ROUTER_TO_EXTERNAL + "-" + uniqueString(5);
749 } else {
750 return ROUTER_TO_EXTERNAL;
751 }
752 }
753
754 @Override
755 public String extToRouterPatchPortName() {
756 if (mode == PASSTHROUGH) {
757 return EXTERNAL_TO_ROUTER + "-" + uniqueString(5);
758 } else {
759 return EXTERNAL_TO_ROUTER;
760 }
761 }
762
763 @Override
764 public String routerPortName() {
765 if (mode == PASSTHROUGH) {
766 return ROUTER + "-" + segmentId();
767 } else {
768 return ROUTER;
769 }
770 }
771
772 @Override
Jian Li49109b52019-01-22 00:17:28 +0900773 public boolean equals(Object obj) {
774 if (this == obj) {
775 return true;
776 }
777
778 if (obj instanceof DefaultK8sNode) {
779 DefaultK8sNode that = (DefaultK8sNode) obj;
780
Jian Lie2a04ce2020-07-01 19:07:02 +0900781 return clusterName.equals(that.clusterName) &&
782 hostname.equals(that.hostname) &&
Jian Li49109b52019-01-22 00:17:28 +0900783 type == that.type &&
Jian Lie2a04ce2020-07-01 19:07:02 +0900784 segmentId == that.segmentId &&
785 mode == that.mode &&
Jian Li49109b52019-01-22 00:17:28 +0900786 intgBridge.equals(that.intgBridge) &&
Jian Libf562c22019-04-15 18:07:14 +0900787 extBridge.equals(that.extBridge) &&
Jian Li1a2eb5d2019-08-27 02:07:05 +0900788 localBridge.equals(that.localBridge) &&
Jian Lie2a04ce2020-07-01 19:07:02 +0900789 tunBridge.equals(that.tunBridge) &&
Jian Li0c632722019-05-08 15:58:04 +0900790 extIntf.equals(that.extIntf) &&
Jian Li49109b52019-01-22 00:17:28 +0900791 managementIp.equals(that.managementIp) &&
792 dataIp.equals(that.dataIp) &&
Jian Lie2a04ce2020-07-01 19:07:02 +0900793 extNetwork.equals(that.extNetwork) &&
Jian Li0c632722019-05-08 15:58:04 +0900794 podCidr.equals(that.podCidr) &&
Jian Li49109b52019-01-22 00:17:28 +0900795 state == that.state;
796 }
797
798 return false;
799 }
800
801 @Override
802 public int hashCode() {
Jian Lie2a04ce2020-07-01 19:07:02 +0900803 return Objects.hash(clusterName, hostname, type, segmentId, mode, intgBridge, extBridge,
804 localBridge, tunBridge, extIntf, managementIp, dataIp, state, extNetwork, podCidr);
Jian Li49109b52019-01-22 00:17:28 +0900805 }
806
807 @Override
808 public String toString() {
809 return MoreObjects.toStringHelper(this)
Jian Lie2a04ce2020-07-01 19:07:02 +0900810 .add("clusterName", clusterName)
Jian Li49109b52019-01-22 00:17:28 +0900811 .add("hostname", hostname)
812 .add("type", type)
Jian Lie2a04ce2020-07-01 19:07:02 +0900813 .add("segmentId", segmentId)
814 .add("mode", mode)
Jian Li49109b52019-01-22 00:17:28 +0900815 .add("intgBridge", intgBridge)
Jian Libf562c22019-04-15 18:07:14 +0900816 .add("extBridge", extBridge)
Jian Li1a2eb5d2019-08-27 02:07:05 +0900817 .add("localBridge", localBridge)
Jian Lie2a04ce2020-07-01 19:07:02 +0900818 .add("tunBridge", tunBridge)
Jian Li0c632722019-05-08 15:58:04 +0900819 .add("extIntf", extIntf)
Jian Li49109b52019-01-22 00:17:28 +0900820 .add("managementIp", managementIp)
821 .add("dataIp", dataIp)
822 .add("state", state)
Jian Lie2a04ce2020-07-01 19:07:02 +0900823 .add("extBridgeIp", extNetwork.extBridgeIp())
824 .add("extGatewayIp", extNetwork.extGatewayIp())
825 .add("extGatewayMac", extNetwork.extGatewayMac())
Jian Li0c632722019-05-08 15:58:04 +0900826 .add("podCidr", podCidr)
Jian Li49109b52019-01-22 00:17:28 +0900827 .toString();
828 }
829
830 private PortNumber tunnelPortNum(String tunnelType) {
831 if (dataIp == null) {
832 return null;
833 }
Jian Lieb488ea2019-04-16 01:50:02 +0900834
Jian Lie2a04ce2020-07-01 19:07:02 +0900835 return portNumber(tunBridge, tunnelType);
Jian Lieb488ea2019-04-16 01:50:02 +0900836 }
837
Jian Li2778ffa2019-05-07 13:21:52 +0900838 private MacAddress macAddress(DeviceId deviceId, String portName) {
839 Port port = port(deviceId, portName);
840 Annotations annots = port.annotations();
841 return annots != null ? MacAddress.valueOf(annots.value(PORT_MAC)) : null;
842 }
843
Jian Lieb488ea2019-04-16 01:50:02 +0900844 private PortNumber portNumber(DeviceId deviceId, String portName) {
Jian Li2778ffa2019-05-07 13:21:52 +0900845 Port port = port(deviceId, portName);
846 return port != null ? port.number() : null;
847 }
848
849 private Port port(DeviceId deviceId, String portName) {
Jian Li49109b52019-01-22 00:17:28 +0900850 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
Jian Li2778ffa2019-05-07 13:21:52 +0900851 return deviceService.getPorts(deviceId).stream()
Jian Li49109b52019-01-22 00:17:28 +0900852 .filter(p -> p.isEnabled() &&
Jian Lieb488ea2019-04-16 01:50:02 +0900853 Objects.equals(p.annotations().value(PORT_NAME), portName))
Jian Li49109b52019-01-22 00:17:28 +0900854 .findAny().orElse(null);
Jian Li49109b52019-01-22 00:17:28 +0900855 }
856
857 /**
858 * Returns new builder instance.
859 *
860 * @return kubernetes node builder
861 */
862 public static Builder builder() {
863 return new Builder();
864 }
865
866 /**
867 * Returns new builder instance with the given node as a default value.
868 *
869 * @param node kubernetes node
870 * @return kubernetes node builder
871 */
872 public static Builder from(K8sNode node) {
873 return new Builder()
874 .hostname(node.hostname())
Jian Lie2a04ce2020-07-01 19:07:02 +0900875 .clusterName(node.clusterName())
Jian Li49109b52019-01-22 00:17:28 +0900876 .type(node.type())
Jian Lie2a04ce2020-07-01 19:07:02 +0900877 .segmentId(node.segmentId())
Jian Li49109b52019-01-22 00:17:28 +0900878 .intgBridge(node.intgBridge())
Jian Libf562c22019-04-15 18:07:14 +0900879 .extBridge(node.extBridge())
Jian Li1a2eb5d2019-08-27 02:07:05 +0900880 .localBridge(node.localBridge())
Jian Lie2a04ce2020-07-01 19:07:02 +0900881 .tunBridge(node.tunBridge())
Jian Li0c632722019-05-08 15:58:04 +0900882 .extIntf(node.extIntf())
Jian Li49109b52019-01-22 00:17:28 +0900883 .managementIp(node.managementIp())
884 .dataIp(node.dataIp())
Jian Li1b08d652019-05-02 17:28:09 +0900885 .state(node.state())
Jian Li0c632722019-05-08 15:58:04 +0900886 .extBridgeIp(node.extBridgeIp())
887 .extGatewayIp(node.extGatewayIp())
888 .extGatewayMac(node.extGatewayMac())
889 .podCidr(node.podCidr());
Jian Li49109b52019-01-22 00:17:28 +0900890 }
891
892 public static final class Builder implements K8sNode.Builder {
893
Jian Lie2a04ce2020-07-01 19:07:02 +0900894 private String clusterName;
Jian Li49109b52019-01-22 00:17:28 +0900895 private String hostname;
896 private Type type;
Jian Lie2a04ce2020-07-01 19:07:02 +0900897 private int segmentId;
898 private Mode mode;
Jian Li49109b52019-01-22 00:17:28 +0900899 private DeviceId intgBridge;
Jian Libf562c22019-04-15 18:07:14 +0900900 private DeviceId extBridge;
Jian Li1a2eb5d2019-08-27 02:07:05 +0900901 private DeviceId localBridge;
Jian Lie2a04ce2020-07-01 19:07:02 +0900902 private DeviceId tunBridge;
Jian Li49109b52019-01-22 00:17:28 +0900903 private IpAddress managementIp;
904 private IpAddress dataIp;
905 private K8sNodeState state;
Jian Li3defa842019-02-12 00:31:35 +0900906 private K8sApiConfig apiConfig;
Jian Li0c632722019-05-08 15:58:04 +0900907 private String extIntf;
908 private IpAddress extBridgeIp;
909 private IpAddress extGatewayIp;
Jian Li1b08d652019-05-02 17:28:09 +0900910 private MacAddress extGatewayMac;
Jian Li0c632722019-05-08 15:58:04 +0900911 private String podCidr;
Jian Li49109b52019-01-22 00:17:28 +0900912
913 // private constructor not intended to use from external
914 private Builder() {
915 }
916
917 @Override
918 public K8sNode build() {
919 checkArgument(hostname != null, NOT_NULL_MSG, "hostname");
920 checkArgument(type != null, NOT_NULL_MSG, "type");
921 checkArgument(state != null, NOT_NULL_MSG, "state");
922 checkArgument(managementIp != null, NOT_NULL_MSG, "management IP");
923
Jian Lie2a04ce2020-07-01 19:07:02 +0900924 if (StringUtils.isEmpty(clusterName)) {
925 clusterName = DEFAULT_CLUSTER_NAME;
926 }
927
928 if (mode == null) {
929 mode = NORMAL;
930 }
931
932 K8sExternalNetwork extNetwork = DefaultK8sExternalNetwork.builder()
933 .extBridgeIp(extBridgeIp)
934 .extGatewayIp(extGatewayIp)
935 .extGatewayMac(extGatewayMac)
936 .build();
937
938 return new DefaultK8sNode(clusterName,
939 hostname,
Jian Li49109b52019-01-22 00:17:28 +0900940 type,
Jian Lie2a04ce2020-07-01 19:07:02 +0900941 segmentId,
942 mode,
Jian Li49109b52019-01-22 00:17:28 +0900943 intgBridge,
Jian Libf562c22019-04-15 18:07:14 +0900944 extBridge,
Jian Li1a2eb5d2019-08-27 02:07:05 +0900945 localBridge,
Jian Lie2a04ce2020-07-01 19:07:02 +0900946 tunBridge,
Jian Li0c632722019-05-08 15:58:04 +0900947 extIntf,
Jian Li49109b52019-01-22 00:17:28 +0900948 managementIp,
949 dataIp,
Jian Li1b08d652019-05-02 17:28:09 +0900950 state,
Jian Lie2a04ce2020-07-01 19:07:02 +0900951 extNetwork,
Jian Li0c632722019-05-08 15:58:04 +0900952 podCidr);
Jian Li49109b52019-01-22 00:17:28 +0900953 }
954
955 @Override
Jian Lie2a04ce2020-07-01 19:07:02 +0900956 public Builder clusterName(String clusterName) {
957 this.clusterName = clusterName;
958 return this;
959 }
960
961 @Override
Jian Li49109b52019-01-22 00:17:28 +0900962 public Builder hostname(String hostname) {
963 this.hostname = hostname;
964 return this;
965 }
966
967 @Override
968 public Builder type(Type type) {
969 this.type = type;
970 return this;
971 }
972
973 @Override
Jian Lie2a04ce2020-07-01 19:07:02 +0900974 public Builder segmentId(int segmentId) {
975 this.segmentId = segmentId;
976 return this;
977 }
978
979 @Override
980 public Builder mode(Mode mode) {
981 this.mode = mode;
982 return this;
983 }
984
985 @Override
Jian Li49109b52019-01-22 00:17:28 +0900986 public Builder intgBridge(DeviceId deviceId) {
987 this.intgBridge = deviceId;
988 return this;
989 }
990
991 @Override
Jian Libf562c22019-04-15 18:07:14 +0900992 public Builder extBridge(DeviceId deviceId) {
993 this.extBridge = deviceId;
994 return this;
995 }
996
997 @Override
Jian Li1a2eb5d2019-08-27 02:07:05 +0900998 public Builder localBridge(DeviceId deviceId) {
999 this.localBridge = deviceId;
1000 return this;
1001 }
1002
1003 @Override
Jian Lie2a04ce2020-07-01 19:07:02 +09001004 public Builder tunBridge(DeviceId deviceId) {
1005 this.tunBridge = deviceId;
1006 return this;
1007 }
1008
1009 @Override
Jian Li0c632722019-05-08 15:58:04 +09001010 public Builder extIntf(String intf) {
1011 this.extIntf = intf;
1012 return this;
1013 }
1014
1015 @Override
Jian Li49109b52019-01-22 00:17:28 +09001016 public Builder managementIp(IpAddress managementIp) {
1017 this.managementIp = managementIp;
1018 return this;
1019 }
1020
1021 @Override
1022 public Builder dataIp(IpAddress dataIp) {
1023 this.dataIp = dataIp;
1024 return this;
1025 }
1026
1027 @Override
1028 public Builder state(K8sNodeState state) {
1029 this.state = state;
1030 return this;
1031 }
Jian Li1b08d652019-05-02 17:28:09 +09001032
1033 @Override
Jian Li0c632722019-05-08 15:58:04 +09001034 public Builder extBridgeIp(IpAddress extBridgeIp) {
1035 this.extBridgeIp = extBridgeIp;
1036 return this;
1037 }
1038
1039 @Override
1040 public Builder extGatewayIp(IpAddress extGatewayIp) {
1041 this.extGatewayIp = extGatewayIp;
1042 return this;
1043 }
1044
1045 @Override
Jian Li1b08d652019-05-02 17:28:09 +09001046 public Builder extGatewayMac(MacAddress extGatewayMac) {
1047 this.extGatewayMac = extGatewayMac;
1048 return this;
1049 }
Jian Li0c632722019-05-08 15:58:04 +09001050
1051 @Override
1052 public Builder podCidr(String podCidr) {
1053 this.podCidr = podCidr;
1054 return this;
1055 }
Jian Li49109b52019-01-22 00:17:28 +09001056 }
1057}