blob: 6bb20017ac5bc1340b3629c5d44802661182ffc3 [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 Li58b33982020-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 Li58b33982020-07-01 19:07:02 +090023import org.onosproject.k8snode.api.K8sApiConfig.Mode;
Jian Li5a9c2bb2019-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 Li58b33982020-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 Li58b33982020-07-01 19:07:02 +090034import static org.onosproject.k8snode.api.Constants.DEFAULT_CLUSTER_NAME;
Jian Lib1218442020-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 Lieb488ea2019-04-16 01:50:02 +090037import static org.onosproject.k8snode.api.Constants.EXTERNAL_BRIDGE;
Jian Li49109b52019-01-22 00:17:28 +090038import static org.onosproject.k8snode.api.Constants.GENEVE_TUNNEL;
39import static org.onosproject.k8snode.api.Constants.GRE_TUNNEL;
Jian Li4aa17642019-01-30 00:01:11 +090040import static org.onosproject.k8snode.api.Constants.INTEGRATION_BRIDGE;
Jian Lieb488ea2019-04-16 01:50:02 +090041import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_EXTERNAL_BRIDGE;
Jian Li121ddfe2019-08-27 02:07:05 +090042import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_LOCAL_BRIDGE;
Jian Li58b33982020-07-01 19:07:02 +090043import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_TUN_BRIDGE;
44import static org.onosproject.k8snode.api.Constants.LOCAL_BRIDGE;
Jian Li121ddfe2019-08-27 02:07:05 +090045import static org.onosproject.k8snode.api.Constants.LOCAL_TO_INTEGRATION_BRIDGE;
Jian Lieb488ea2019-04-16 01:50:02 +090046import static org.onosproject.k8snode.api.Constants.PHYSICAL_EXTERNAL_BRIDGE;
Jian Li58b33982020-07-01 19:07:02 +090047import static org.onosproject.k8snode.api.Constants.TUNNEL_BRIDGE;
48import static org.onosproject.k8snode.api.Constants.TUN_TO_INTEGRATION_BRIDGE;
Jian Li49109b52019-01-22 00:17:28 +090049import static org.onosproject.k8snode.api.Constants.VXLAN_TUNNEL;
Jian Li58b33982020-07-01 19:07:02 +090050import static org.onosproject.k8snode.api.K8sApiConfig.Mode.NORMAL;
51import static org.onosproject.k8snode.api.K8sApiConfig.Mode.PASSTHROUGH;
Jian Li49109b52019-01-22 00:17:28 +090052import static org.onosproject.net.AnnotationKeys.PORT_NAME;
53
54/**
55 * Representation of a kubernetes node.
56 */
57public class DefaultK8sNode implements K8sNode {
58
Jian Li5a9c2bb2019-05-07 13:21:52 +090059 private static final String PORT_MAC = "portMac";
Jian Li58b33982020-07-01 19:07:02 +090060 private static final String FLOW_KEY = "flow";
Jian Li7d111d72019-04-12 13:58:44 +090061
Jian Li58b33982020-07-01 19:07:02 +090062 private static final int SHORT_NAME_LENGTH = 10;
63
64 private final String clusterName;
Jian Li49109b52019-01-22 00:17:28 +090065 private final String hostname;
66 private final Type type;
Jian Li58b33982020-07-01 19:07:02 +090067 private final int segmentId;
68 private final Mode mode;
Jian Li49109b52019-01-22 00:17:28 +090069 private final DeviceId intgBridge;
Jian Libf562c22019-04-15 18:07:14 +090070 private final DeviceId extBridge;
Jian Li121ddfe2019-08-27 02:07:05 +090071 private final DeviceId localBridge;
Jian Li58b33982020-07-01 19:07:02 +090072 private final DeviceId tunBridge;
Jian Li49109b52019-01-22 00:17:28 +090073 private final IpAddress managementIp;
74 private final IpAddress dataIp;
75 private final K8sNodeState state;
Jian Li7709eb42019-05-08 15:58:04 +090076 private final String extIntf;
Jian Li58b33982020-07-01 19:07:02 +090077 private final K8sExternalNetwork extNetwork;
Jian Li7709eb42019-05-08 15:58:04 +090078 private final String podCidr;
Jian Li49109b52019-01-22 00:17:28 +090079
80 private static final String NOT_NULL_MSG = "Node % cannot be null";
81
82 private static final String OVSDB = "ovsdb:";
83
84 /**
85 * A default constructor of kubernetes Node.
86 *
Jian Li58b33982020-07-01 19:07:02 +090087 * @param clusterName clusterName
Jian Li49109b52019-01-22 00:17:28 +090088 * @param hostname hostname
89 * @param type node type
Jian Li58b33982020-07-01 19:07:02 +090090 * @param segmentId segment identifier
91 * @param mode CNI running mode
Jian Li49109b52019-01-22 00:17:28 +090092 * @param intgBridge integration bridge
Jian Libf562c22019-04-15 18:07:14 +090093 * @param extBridge external bridge
Jian Li121ddfe2019-08-27 02:07:05 +090094 * @param localBridge local bridge
Jian Li58b33982020-07-01 19:07:02 +090095 * @param tunBridge tunnel bridge
Jian Li7709eb42019-05-08 15:58:04 +090096 * @param extIntf external interface
Jian Li49109b52019-01-22 00:17:28 +090097 * @param managementIp management IP address
98 * @param dataIp data IP address
99 * @param state node state
Jian Li58b33982020-07-01 19:07:02 +0900100 * @param extNetwork external network
Jian Li7709eb42019-05-08 15:58:04 +0900101 * @param podCidr POD CIDR
Jian Li49109b52019-01-22 00:17:28 +0900102 */
Jian Li58b33982020-07-01 19:07:02 +0900103 protected DefaultK8sNode(String clusterName, String hostname, Type type,
104 int segmentId, Mode mode, DeviceId intgBridge,
Jian Li121ddfe2019-08-27 02:07:05 +0900105 DeviceId extBridge, DeviceId localBridge,
Jian Li58b33982020-07-01 19:07:02 +0900106 DeviceId tunBridge, String extIntf, IpAddress managementIp,
Jian Li121ddfe2019-08-27 02:07:05 +0900107 IpAddress dataIp, K8sNodeState state,
Jian Li58b33982020-07-01 19:07:02 +0900108 K8sExternalNetwork extNetwork, String podCidr) {
109 this.clusterName = clusterName;
Jian Li49109b52019-01-22 00:17:28 +0900110 this.hostname = hostname;
111 this.type = type;
Jian Li58b33982020-07-01 19:07:02 +0900112 this.mode = mode;
113 this.segmentId = segmentId;
Jian Li49109b52019-01-22 00:17:28 +0900114 this.intgBridge = intgBridge;
Jian Libf562c22019-04-15 18:07:14 +0900115 this.extBridge = extBridge;
Jian Li121ddfe2019-08-27 02:07:05 +0900116 this.localBridge = localBridge;
Jian Li58b33982020-07-01 19:07:02 +0900117 this.tunBridge = tunBridge;
Jian Li7709eb42019-05-08 15:58:04 +0900118 this.extIntf = extIntf;
Jian Li49109b52019-01-22 00:17:28 +0900119 this.managementIp = managementIp;
120 this.dataIp = dataIp;
121 this.state = state;
Jian Li58b33982020-07-01 19:07:02 +0900122 this.extNetwork = extNetwork;
Jian Li7709eb42019-05-08 15:58:04 +0900123 this.podCidr = podCidr;
Jian Li49109b52019-01-22 00:17:28 +0900124 }
125
126 @Override
Jian Li58b33982020-07-01 19:07:02 +0900127 public String clusterName() {
128 return clusterName;
129 }
130
131 @Override
132 public String hostShortName() {
133 return StringUtils.substring(hostname, 0, SHORT_NAME_LENGTH);
134 }
135
136 @Override
137 public String uniqueString(int length) {
138 String uuid = UUID.nameUUIDFromBytes(hostname.getBytes()).toString();
139 return StringUtils.substring(uuid, 0, length);
140 }
141
142 @Override
143 public int segmentId() {
144 return segmentId;
145 }
146
147 @Override
148 public String tunnelKey() {
149 if (mode == PASSTHROUGH) {
150 return String.valueOf(segmentId);
151 } else {
152 return FLOW_KEY;
153 }
154 }
155
156 @Override
157 public Mode mode() {
158 return mode;
159 }
160
161 @Override
Jian Li49109b52019-01-22 00:17:28 +0900162 public String hostname() {
163 return hostname;
164 }
165
166 @Override
167 public Type type() {
168 return type;
169 }
170
171 @Override
172 public DeviceId ovsdb() {
173 return DeviceId.deviceId(OVSDB + managementIp().toString());
174 }
175
176 @Override
177 public DeviceId intgBridge() {
178 return intgBridge;
179 }
180
181 @Override
Jian Libf562c22019-04-15 18:07:14 +0900182 public DeviceId extBridge() {
183 return extBridge;
184 }
185
186 @Override
Jian Li121ddfe2019-08-27 02:07:05 +0900187 public DeviceId localBridge() {
188 return localBridge;
189 }
190
191 @Override
Jian Li58b33982020-07-01 19:07:02 +0900192 public DeviceId tunBridge() {
Jian Li3cb86e32020-09-07 17:01:11 +0900193
194 if (mode == PASSTHROUGH) {
195 K8sHostService hostService =
196 DefaultServiceDirectory.getService(K8sHostService.class);
197 DeviceId deviceId = null;
198 for (K8sHost host : hostService.hosts()) {
199 if (host.nodeNames().contains(hostname())) {
200 for (K8sTunnelBridge bridge : host.tunBridges()) {
201 if (bridge.tunnelId() == segmentId()) {
202 deviceId = bridge.deviceId();
203 }
204 }
205 }
206 }
207 return deviceId;
208 } else {
209 return tunBridge;
210 }
Jian Li58b33982020-07-01 19:07:02 +0900211 }
212
213 @Override
Jian Li7709eb42019-05-08 15:58:04 +0900214 public String extIntf() {
215 return extIntf;
216 }
217
218 @Override
Jian Li1cee9882019-02-13 11:25:25 +0900219 public K8sNode updateIntgBridge(DeviceId deviceId) {
220 return new Builder()
221 .hostname(hostname)
Jian Li58b33982020-07-01 19:07:02 +0900222 .clusterName(clusterName)
Jian Li1cee9882019-02-13 11:25:25 +0900223 .type(type)
Jian Li58b33982020-07-01 19:07:02 +0900224 .segmentId(segmentId)
225 .mode(mode)
Jian Li1cee9882019-02-13 11:25:25 +0900226 .intgBridge(deviceId)
Jian Libf562c22019-04-15 18:07:14 +0900227 .extBridge(extBridge)
Jian Li121ddfe2019-08-27 02:07:05 +0900228 .localBridge(localBridge)
Jian Li58b33982020-07-01 19:07:02 +0900229 .tunBridge(tunBridge)
Jian Li7709eb42019-05-08 15:58:04 +0900230 .extIntf(extIntf)
Jian Libf562c22019-04-15 18:07:14 +0900231 .managementIp(managementIp)
232 .dataIp(dataIp)
233 .state(state)
Jian Li58b33982020-07-01 19:07:02 +0900234 .extBridgeIp(extNetwork.extBridgeIp())
235 .extGatewayIp(extNetwork.extGatewayIp())
236 .extGatewayMac(extNetwork.extGatewayMac())
Jian Li7709eb42019-05-08 15:58:04 +0900237 .podCidr(podCidr)
Jian Libf562c22019-04-15 18:07:14 +0900238 .build();
239 }
240
241 @Override
242 public K8sNode updateExtBridge(DeviceId deviceId) {
243 return new Builder()
244 .hostname(hostname)
Jian Li58b33982020-07-01 19:07:02 +0900245 .clusterName(clusterName)
Jian Libf562c22019-04-15 18:07:14 +0900246 .type(type)
Jian Li58b33982020-07-01 19:07:02 +0900247 .segmentId(segmentId)
248 .mode(mode)
Jian Libf562c22019-04-15 18:07:14 +0900249 .intgBridge(intgBridge)
250 .extBridge(deviceId)
Jian Li121ddfe2019-08-27 02:07:05 +0900251 .localBridge(localBridge)
Jian Li58b33982020-07-01 19:07:02 +0900252 .tunBridge(tunBridge)
Jian Li121ddfe2019-08-27 02:07:05 +0900253 .extIntf(extIntf)
254 .managementIp(managementIp)
255 .dataIp(dataIp)
256 .state(state)
Jian Li58b33982020-07-01 19:07:02 +0900257 .extBridgeIp(extNetwork.extBridgeIp())
258 .extGatewayIp(extNetwork.extGatewayIp())
259 .extGatewayMac(extNetwork.extGatewayMac())
Jian Li121ddfe2019-08-27 02:07:05 +0900260 .podCidr(podCidr)
261 .build();
262 }
263
264 @Override
265 public K8sNode updateLocalBridge(DeviceId deviceId) {
266 return new Builder()
267 .hostname(hostname)
Jian Li58b33982020-07-01 19:07:02 +0900268 .clusterName(clusterName)
Jian Li121ddfe2019-08-27 02:07:05 +0900269 .type(type)
Jian Li58b33982020-07-01 19:07:02 +0900270 .segmentId(segmentId)
271 .mode(mode)
Jian Li121ddfe2019-08-27 02:07:05 +0900272 .intgBridge(intgBridge)
273 .extBridge(extBridge)
274 .localBridge(deviceId)
Jian Li58b33982020-07-01 19:07:02 +0900275 .tunBridge(tunBridge)
Jian Li7709eb42019-05-08 15:58:04 +0900276 .extIntf(extIntf)
Jian Li1cee9882019-02-13 11:25:25 +0900277 .managementIp(managementIp)
278 .dataIp(dataIp)
279 .state(state)
Jian Li58b33982020-07-01 19:07:02 +0900280 .extBridgeIp(extNetwork.extBridgeIp())
281 .extGatewayIp(extNetwork.extGatewayIp())
282 .extGatewayMac(extNetwork.extGatewayMac())
283 .podCidr(podCidr)
284 .build();
285 }
286
287 @Override
288 public K8sNode updateTunBridge(DeviceId deviceId) {
289 return new Builder()
290 .hostname(hostname)
291 .clusterName(clusterName)
292 .type(type)
293 .segmentId(segmentId)
294 .mode(mode)
295 .intgBridge(intgBridge)
296 .extBridge(extBridge)
297 .localBridge(localBridge)
298 .tunBridge(deviceId)
299 .extIntf(extIntf)
300 .managementIp(managementIp)
301 .dataIp(dataIp)
302 .state(state)
303 .extBridgeIp(extNetwork.extBridgeIp())
304 .extGatewayIp(extNetwork.extGatewayIp())
305 .extGatewayMac(extNetwork.extGatewayMac())
Jian Li7709eb42019-05-08 15:58:04 +0900306 .podCidr(podCidr)
Jian Li1cee9882019-02-13 11:25:25 +0900307 .build();
308 }
309
310 @Override
Jian Li49109b52019-01-22 00:17:28 +0900311 public IpAddress managementIp() {
312 return managementIp;
313 }
314
315 @Override
316 public IpAddress dataIp() {
317 return dataIp;
318 }
319
320 @Override
321 public K8sNodeState state() {
322 return state;
323 }
324
325 @Override
Jian Li7709eb42019-05-08 15:58:04 +0900326 public String podCidr() {
327 return podCidr;
328 }
329
330 @Override
Jian Li49109b52019-01-22 00:17:28 +0900331 public K8sNode updateState(K8sNodeState newState) {
332 return new Builder()
333 .hostname(hostname)
Jian Li58b33982020-07-01 19:07:02 +0900334 .clusterName(clusterName)
Jian Li49109b52019-01-22 00:17:28 +0900335 .type(type)
Jian Li58b33982020-07-01 19:07:02 +0900336 .segmentId(segmentId)
337 .mode(mode)
Jian Li49109b52019-01-22 00:17:28 +0900338 .intgBridge(intgBridge)
Jian Li7709eb42019-05-08 15:58:04 +0900339 .extBridge(extBridge)
Jian Li121ddfe2019-08-27 02:07:05 +0900340 .localBridge(localBridge)
Jian Li58b33982020-07-01 19:07:02 +0900341 .tunBridge(tunBridge)
Jian Li7709eb42019-05-08 15:58:04 +0900342 .extIntf(extIntf)
Jian Li49109b52019-01-22 00:17:28 +0900343 .managementIp(managementIp)
344 .dataIp(dataIp)
345 .state(newState)
Jian Li58b33982020-07-01 19:07:02 +0900346 .extBridgeIp(extNetwork.extBridgeIp())
347 .extGatewayIp(extNetwork.extGatewayIp())
348 .extGatewayMac(extNetwork.extGatewayMac())
Jian Li7709eb42019-05-08 15:58:04 +0900349 .podCidr(podCidr)
Jian Li49109b52019-01-22 00:17:28 +0900350 .build();
351 }
352
353 @Override
Jian Li1b08d652019-05-02 17:28:09 +0900354 public K8sNode updateExtGatewayMac(MacAddress newMac) {
355 return new Builder()
356 .hostname(hostname)
Jian Li58b33982020-07-01 19:07:02 +0900357 .clusterName(clusterName)
Jian Li1b08d652019-05-02 17:28:09 +0900358 .type(type)
Jian Li58b33982020-07-01 19:07:02 +0900359 .segmentId(segmentId)
360 .mode(mode)
Jian Li1b08d652019-05-02 17:28:09 +0900361 .intgBridge(intgBridge)
Jian Li7709eb42019-05-08 15:58:04 +0900362 .extBridge(extBridge)
Jian Li121ddfe2019-08-27 02:07:05 +0900363 .localBridge(localBridge)
Jian Li58b33982020-07-01 19:07:02 +0900364 .tunBridge(tunBridge)
Jian Li7709eb42019-05-08 15:58:04 +0900365 .extIntf(extIntf)
Jian Li1b08d652019-05-02 17:28:09 +0900366 .managementIp(managementIp)
367 .dataIp(dataIp)
368 .state(state)
Jian Li58b33982020-07-01 19:07:02 +0900369 .extBridgeIp(extNetwork.extBridgeIp())
370 .extGatewayIp(extNetwork.extGatewayIp())
Jian Li1b08d652019-05-02 17:28:09 +0900371 .extGatewayMac(newMac)
Jian Li7709eb42019-05-08 15:58:04 +0900372 .podCidr(podCidr)
Jian Li1b08d652019-05-02 17:28:09 +0900373 .build();
Jian Li1b08d652019-05-02 17:28:09 +0900374 }
375
376 @Override
Jian Li49109b52019-01-22 00:17:28 +0900377 public PortNumber grePortNum() {
Jian Li58b33982020-07-01 19:07:02 +0900378 return tunnelPortNum(grePortName());
Jian Li49109b52019-01-22 00:17:28 +0900379 }
380
381 @Override
382 public PortNumber vxlanPortNum() {
Jian Li58b33982020-07-01 19:07:02 +0900383 return tunnelPortNum(vxlanPortName());
Jian Li49109b52019-01-22 00:17:28 +0900384 }
385
386 @Override
387 public PortNumber genevePortNum() {
Jian Li58b33982020-07-01 19:07:02 +0900388 return tunnelPortNum(genevePortName());
Jian Li49109b52019-01-22 00:17:28 +0900389 }
390
391 @Override
Jian Lieb488ea2019-04-16 01:50:02 +0900392 public PortNumber intgBridgePortNum() {
Jian Li89164182020-09-04 19:38:37 +0900393 return PortNumber.LOCAL;
Jian Lieb488ea2019-04-16 01:50:02 +0900394 }
395
396 @Override
397 public PortNumber intgToExtPatchPortNum() {
Jian Li58b33982020-07-01 19:07:02 +0900398 return portNumber(intgBridge, intgToExtPatchPortName());
Jian Lieb488ea2019-04-16 01:50:02 +0900399 }
400
401 @Override
Jian Li121ddfe2019-08-27 02:07:05 +0900402 public PortNumber intgToLocalPatchPortNum() {
Jian Li58b33982020-07-01 19:07:02 +0900403 return portNumber(intgBridge, intgToLocalPatchPortName());
Jian Li121ddfe2019-08-27 02:07:05 +0900404 }
405
406 @Override
Jian Li58b33982020-07-01 19:07:02 +0900407 public PortNumber localToIntgPatchPortNum() {
408 return portNumber(localBridge, localToIntgPatchPortName());
Jian Li121ddfe2019-08-27 02:07:05 +0900409 }
410
411 @Override
Jian Lieb488ea2019-04-16 01:50:02 +0900412 public PortNumber extToIntgPatchPortNum() {
Jian Li58b33982020-07-01 19:07:02 +0900413 return portNumber(extBridge, extToIntgPatchPortName());
Jian Lieb488ea2019-04-16 01:50:02 +0900414 }
415
416 @Override
Jian Li1ecfbb72020-09-02 14:45:35 +0900417 public PortNumber intgToTunPortNum() {
418 return portNumber(intgBridge, intgToTunPatchPortName());
419 }
420
421 @Override
422 public PortNumber tunToIntgPortNum() {
Jian Li3cb86e32020-09-07 17:01:11 +0900423 if (mode() == PASSTHROUGH) {
424 K8sHostService hostService =
425 DefaultServiceDirectory.getService(K8sHostService.class);
426 Port port = null;
427 for (K8sHost host : hostService.hosts()) {
428 if (host.nodeNames().contains(hostname())) {
429 for (K8sTunnelBridge bridge : host.tunBridges()) {
430 if (bridge.tunnelId() == segmentId()) {
431 port = port(bridge.deviceId(), tunToIntgPatchPortName());
432 }
433 }
434 }
435 }
436
437 if (port == null) {
438 return null;
439 } else {
440 return port.number();
441 }
442 } else {
443 return portNumber(tunBridge, tunToIntgPatchPortName());
444 }
Jian Li1ecfbb72020-09-02 14:45:35 +0900445 }
446
447 @Override
Jian Lieb488ea2019-04-16 01:50:02 +0900448 public PortNumber extBridgePortNum() {
Jian Li89164182020-09-04 19:38:37 +0900449 return PortNumber.LOCAL;
Jian Lieb488ea2019-04-16 01:50:02 +0900450 }
451
452 @Override
Jian Lib1218442020-09-03 13:12:14 +0900453 public PortNumber extIntfPortNum() {
454 if (this.extIntf == null) {
455 return null;
456 }
457 return portNumber(extBridge, extIntf());
458 }
459
460 @Override
Jian Li5a9c2bb2019-05-07 13:21:52 +0900461 public MacAddress intgBridgeMac() {
Jian Li58b33982020-07-01 19:07:02 +0900462 return macAddress(intgBridge, intgBridgeName());
Jian Li5a9c2bb2019-05-07 13:21:52 +0900463 }
464
465 @Override
466 public IpAddress extBridgeIp() {
Jian Li58b33982020-07-01 19:07:02 +0900467 return extNetwork.extBridgeIp();
Jian Li5a9c2bb2019-05-07 13:21:52 +0900468 }
469
470 @Override
471 public MacAddress extBridgeMac() {
Jian Lib1218442020-09-03 13:12:14 +0900472 if (MacAddress.valueOf(DEFAULT_EXTERNAL_GATEWAY_MAC).equals(extGatewayMac())) {
473 return MacAddress.valueOf(DEFAULT_EXTERNAL_BRIDGE_MAC);
474 } else {
475 return macAddress(extBridge, extBridgeName());
476 }
Jian Li5a9c2bb2019-05-07 13:21:52 +0900477 }
478
479 @Override
480 public IpAddress extGatewayIp() {
Jian Li58b33982020-07-01 19:07:02 +0900481 return extNetwork.extGatewayIp();
Jian Li5a9c2bb2019-05-07 13:21:52 +0900482 }
483
484 @Override
485 public MacAddress extGatewayMac() {
Jian Li58b33982020-07-01 19:07:02 +0900486 return extNetwork.extGatewayMac();
487 }
488
489 @Override
490 public String grePortName() {
491 if (mode == PASSTHROUGH) {
492 return GRE_TUNNEL + "-" + segmentId;
493 } else {
494 return GRE_TUNNEL;
495 }
496 }
497
498 @Override
499 public String vxlanPortName() {
500 if (mode == PASSTHROUGH) {
501 return VXLAN_TUNNEL + "-" + segmentId;
502 } else {
503 return VXLAN_TUNNEL;
504 }
505 }
506
507 @Override
508 public String genevePortName() {
509 if (mode == PASSTHROUGH) {
510 return GENEVE_TUNNEL + "-" + segmentId;
511 } else {
512 return GENEVE_TUNNEL;
513 }
514 }
515
516 @Override
517 public String intgBridgeName() {
518 if (mode == PASSTHROUGH) {
519 return INTEGRATION_BRIDGE + "-" + uniqueString(5);
520 } else {
521 return INTEGRATION_BRIDGE;
522 }
523 }
524
525 @Override
526 public String extBridgeName() {
527 if (mode == PASSTHROUGH) {
528 return EXTERNAL_BRIDGE + "-" + uniqueString(5);
529 } else {
530 return EXTERNAL_BRIDGE;
531 }
532 }
533
534 @Override
535 public String localBridgeName() {
536 if (mode == PASSTHROUGH) {
537 return LOCAL_BRIDGE + "-" + uniqueString(5);
538 } else {
539 return LOCAL_BRIDGE;
540 }
541 }
542
543 @Override
544 public String tunBridgeName() {
545 if (mode == PASSTHROUGH) {
546 return TUNNEL_BRIDGE + "-" + segmentId;
547 } else {
548 return TUNNEL_BRIDGE;
549 }
550 }
551
552 @Override
553 public String intgBridgePortName() {
554 if (mode == PASSTHROUGH) {
555 return INTEGRATION_BRIDGE + "-" + uniqueString(5);
556 } else {
557 return INTEGRATION_BRIDGE;
558 }
559 }
560
561 @Override
562 public String extBridgePortName() {
563 if (mode == PASSTHROUGH) {
564 return EXTERNAL_BRIDGE + "-" + uniqueString(5);
565 } else {
566 return EXTERNAL_BRIDGE;
567 }
568 }
569
570 @Override
571 public String localBridgePortName() {
572 if (mode == PASSTHROUGH) {
573 return LOCAL_BRIDGE + "-" + uniqueString(5);
574 } else {
575 return LOCAL_BRIDGE;
576 }
577 }
578
579 @Override
Jian Li1ecfbb72020-09-02 14:45:35 +0900580 public String tunBridgePortName() {
581 if (mode == PASSTHROUGH) {
582 return TUNNEL_BRIDGE + "-" + uniqueString(5);
583 } else {
584 return TUNNEL_BRIDGE;
585 }
586 }
587
588 @Override
Jian Li58b33982020-07-01 19:07:02 +0900589 public String intgToExtPatchPortName() {
590 if (mode == PASSTHROUGH) {
591 return INTEGRATION_TO_EXTERNAL_BRIDGE + "-" + uniqueString(5);
592 } else {
593 return INTEGRATION_TO_EXTERNAL_BRIDGE;
594 }
595 }
596
597 @Override
598 public String intgToTunPatchPortName() {
599 if (mode == PASSTHROUGH) {
600 return INTEGRATION_TO_TUN_BRIDGE + "-" + uniqueString(5);
601 } else {
602 return INTEGRATION_TO_TUN_BRIDGE;
603 }
604 }
605
606 @Override
607 public String intgToLocalPatchPortName() {
608 if (mode == PASSTHROUGH) {
609 return INTEGRATION_TO_LOCAL_BRIDGE + "-" + uniqueString(5);
610 } else {
611 return INTEGRATION_TO_LOCAL_BRIDGE;
612 }
613 }
614
615 @Override
616 public String localToIntgPatchPortName() {
617 if (mode == PASSTHROUGH) {
618 return LOCAL_TO_INTEGRATION_BRIDGE + "-" + uniqueString(5);
619 } else {
620 return LOCAL_TO_INTEGRATION_BRIDGE;
621 }
622 }
623
624 @Override
625 public String extToIntgPatchPortName() {
626 if (mode == PASSTHROUGH) {
627 return PHYSICAL_EXTERNAL_BRIDGE + "-" + uniqueString(5);
628 } else {
629 return PHYSICAL_EXTERNAL_BRIDGE;
630 }
631 }
632
633 @Override
634 public String tunToIntgPatchPortName() {
635 if (mode == PASSTHROUGH) {
636 return TUN_TO_INTEGRATION_BRIDGE + "-" + uniqueString(5);
637 } else {
638 return TUN_TO_INTEGRATION_BRIDGE;
639 }
Jian Li5a9c2bb2019-05-07 13:21:52 +0900640 }
641
642 @Override
Jian Li49109b52019-01-22 00:17:28 +0900643 public boolean equals(Object obj) {
644 if (this == obj) {
645 return true;
646 }
647
648 if (obj instanceof DefaultK8sNode) {
649 DefaultK8sNode that = (DefaultK8sNode) obj;
650
Jian Li58b33982020-07-01 19:07:02 +0900651 return clusterName.equals(that.clusterName) &&
652 hostname.equals(that.hostname) &&
Jian Li49109b52019-01-22 00:17:28 +0900653 type == that.type &&
Jian Li58b33982020-07-01 19:07:02 +0900654 segmentId == that.segmentId &&
655 mode == that.mode &&
Jian Li49109b52019-01-22 00:17:28 +0900656 intgBridge.equals(that.intgBridge) &&
Jian Libf562c22019-04-15 18:07:14 +0900657 extBridge.equals(that.extBridge) &&
Jian Li121ddfe2019-08-27 02:07:05 +0900658 localBridge.equals(that.localBridge) &&
Jian Li58b33982020-07-01 19:07:02 +0900659 tunBridge.equals(that.tunBridge) &&
Jian Li7709eb42019-05-08 15:58:04 +0900660 extIntf.equals(that.extIntf) &&
Jian Li49109b52019-01-22 00:17:28 +0900661 managementIp.equals(that.managementIp) &&
662 dataIp.equals(that.dataIp) &&
Jian Li58b33982020-07-01 19:07:02 +0900663 extNetwork.equals(that.extNetwork) &&
Jian Li7709eb42019-05-08 15:58:04 +0900664 podCidr.equals(that.podCidr) &&
Jian Li49109b52019-01-22 00:17:28 +0900665 state == that.state;
666 }
667
668 return false;
669 }
670
671 @Override
672 public int hashCode() {
Jian Li58b33982020-07-01 19:07:02 +0900673 return Objects.hash(clusterName, hostname, type, segmentId, mode, intgBridge, extBridge,
674 localBridge, tunBridge, extIntf, managementIp, dataIp, state, extNetwork, podCidr);
Jian Li49109b52019-01-22 00:17:28 +0900675 }
676
677 @Override
678 public String toString() {
679 return MoreObjects.toStringHelper(this)
Jian Li58b33982020-07-01 19:07:02 +0900680 .add("clusterName", clusterName)
Jian Li49109b52019-01-22 00:17:28 +0900681 .add("hostname", hostname)
682 .add("type", type)
Jian Li58b33982020-07-01 19:07:02 +0900683 .add("segmentId", segmentId)
684 .add("mode", mode)
Jian Li49109b52019-01-22 00:17:28 +0900685 .add("intgBridge", intgBridge)
Jian Libf562c22019-04-15 18:07:14 +0900686 .add("extBridge", extBridge)
Jian Li121ddfe2019-08-27 02:07:05 +0900687 .add("localBridge", localBridge)
Jian Li58b33982020-07-01 19:07:02 +0900688 .add("tunBridge", tunBridge)
Jian Li7709eb42019-05-08 15:58:04 +0900689 .add("extIntf", extIntf)
Jian Li49109b52019-01-22 00:17:28 +0900690 .add("managementIp", managementIp)
691 .add("dataIp", dataIp)
692 .add("state", state)
Jian Li58b33982020-07-01 19:07:02 +0900693 .add("extBridgeIp", extNetwork.extBridgeIp())
694 .add("extGatewayIp", extNetwork.extGatewayIp())
695 .add("extGatewayMac", extNetwork.extGatewayMac())
Jian Li7709eb42019-05-08 15:58:04 +0900696 .add("podCidr", podCidr)
Jian Li49109b52019-01-22 00:17:28 +0900697 .toString();
698 }
699
700 private PortNumber tunnelPortNum(String tunnelType) {
701 if (dataIp == null) {
702 return null;
703 }
Jian Lieb488ea2019-04-16 01:50:02 +0900704
Jian Li58b33982020-07-01 19:07:02 +0900705 return portNumber(tunBridge, tunnelType);
Jian Lieb488ea2019-04-16 01:50:02 +0900706 }
707
Jian Li5a9c2bb2019-05-07 13:21:52 +0900708 private MacAddress macAddress(DeviceId deviceId, String portName) {
709 Port port = port(deviceId, portName);
710 Annotations annots = port.annotations();
711 return annots != null ? MacAddress.valueOf(annots.value(PORT_MAC)) : null;
712 }
713
Jian Lieb488ea2019-04-16 01:50:02 +0900714 private PortNumber portNumber(DeviceId deviceId, String portName) {
Jian Li5a9c2bb2019-05-07 13:21:52 +0900715 Port port = port(deviceId, portName);
716 return port != null ? port.number() : null;
717 }
718
719 private Port port(DeviceId deviceId, String portName) {
Jian Li49109b52019-01-22 00:17:28 +0900720 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
Jian Li5a9c2bb2019-05-07 13:21:52 +0900721 return deviceService.getPorts(deviceId).stream()
Jian Li49109b52019-01-22 00:17:28 +0900722 .filter(p -> p.isEnabled() &&
Jian Lieb488ea2019-04-16 01:50:02 +0900723 Objects.equals(p.annotations().value(PORT_NAME), portName))
Jian Li49109b52019-01-22 00:17:28 +0900724 .findAny().orElse(null);
Jian Li49109b52019-01-22 00:17:28 +0900725 }
726
727 /**
728 * Returns new builder instance.
729 *
730 * @return kubernetes node builder
731 */
732 public static Builder builder() {
733 return new Builder();
734 }
735
736 /**
737 * Returns new builder instance with the given node as a default value.
738 *
739 * @param node kubernetes node
740 * @return kubernetes node builder
741 */
742 public static Builder from(K8sNode node) {
743 return new Builder()
744 .hostname(node.hostname())
Jian Li58b33982020-07-01 19:07:02 +0900745 .clusterName(node.clusterName())
Jian Li49109b52019-01-22 00:17:28 +0900746 .type(node.type())
Jian Li58b33982020-07-01 19:07:02 +0900747 .segmentId(node.segmentId())
Jian Li49109b52019-01-22 00:17:28 +0900748 .intgBridge(node.intgBridge())
Jian Libf562c22019-04-15 18:07:14 +0900749 .extBridge(node.extBridge())
Jian Li121ddfe2019-08-27 02:07:05 +0900750 .localBridge(node.localBridge())
Jian Li58b33982020-07-01 19:07:02 +0900751 .tunBridge(node.tunBridge())
Jian Li7709eb42019-05-08 15:58:04 +0900752 .extIntf(node.extIntf())
Jian Li49109b52019-01-22 00:17:28 +0900753 .managementIp(node.managementIp())
754 .dataIp(node.dataIp())
Jian Li1b08d652019-05-02 17:28:09 +0900755 .state(node.state())
Jian Li7709eb42019-05-08 15:58:04 +0900756 .extBridgeIp(node.extBridgeIp())
757 .extGatewayIp(node.extGatewayIp())
758 .extGatewayMac(node.extGatewayMac())
759 .podCidr(node.podCidr());
Jian Li49109b52019-01-22 00:17:28 +0900760 }
761
762 public static final class Builder implements K8sNode.Builder {
763
Jian Li58b33982020-07-01 19:07:02 +0900764 private String clusterName;
Jian Li49109b52019-01-22 00:17:28 +0900765 private String hostname;
766 private Type type;
Jian Li58b33982020-07-01 19:07:02 +0900767 private int segmentId;
768 private Mode mode;
Jian Li49109b52019-01-22 00:17:28 +0900769 private DeviceId intgBridge;
Jian Libf562c22019-04-15 18:07:14 +0900770 private DeviceId extBridge;
Jian Li121ddfe2019-08-27 02:07:05 +0900771 private DeviceId localBridge;
Jian Li58b33982020-07-01 19:07:02 +0900772 private DeviceId tunBridge;
Jian Li49109b52019-01-22 00:17:28 +0900773 private IpAddress managementIp;
774 private IpAddress dataIp;
775 private K8sNodeState state;
Jian Li3defa842019-02-12 00:31:35 +0900776 private K8sApiConfig apiConfig;
Jian Li7709eb42019-05-08 15:58:04 +0900777 private String extIntf;
778 private IpAddress extBridgeIp;
779 private IpAddress extGatewayIp;
Jian Li1b08d652019-05-02 17:28:09 +0900780 private MacAddress extGatewayMac;
Jian Li7709eb42019-05-08 15:58:04 +0900781 private String podCidr;
Jian Li49109b52019-01-22 00:17:28 +0900782
783 // private constructor not intended to use from external
784 private Builder() {
785 }
786
787 @Override
788 public K8sNode build() {
789 checkArgument(hostname != null, NOT_NULL_MSG, "hostname");
790 checkArgument(type != null, NOT_NULL_MSG, "type");
791 checkArgument(state != null, NOT_NULL_MSG, "state");
792 checkArgument(managementIp != null, NOT_NULL_MSG, "management IP");
793
Jian Li58b33982020-07-01 19:07:02 +0900794 if (StringUtils.isEmpty(clusterName)) {
795 clusterName = DEFAULT_CLUSTER_NAME;
796 }
797
798 if (mode == null) {
799 mode = NORMAL;
800 }
801
802 K8sExternalNetwork extNetwork = DefaultK8sExternalNetwork.builder()
803 .extBridgeIp(extBridgeIp)
804 .extGatewayIp(extGatewayIp)
805 .extGatewayMac(extGatewayMac)
806 .build();
807
808 return new DefaultK8sNode(clusterName,
809 hostname,
Jian Li49109b52019-01-22 00:17:28 +0900810 type,
Jian Li58b33982020-07-01 19:07:02 +0900811 segmentId,
812 mode,
Jian Li49109b52019-01-22 00:17:28 +0900813 intgBridge,
Jian Libf562c22019-04-15 18:07:14 +0900814 extBridge,
Jian Li121ddfe2019-08-27 02:07:05 +0900815 localBridge,
Jian Li58b33982020-07-01 19:07:02 +0900816 tunBridge,
Jian Li7709eb42019-05-08 15:58:04 +0900817 extIntf,
Jian Li49109b52019-01-22 00:17:28 +0900818 managementIp,
819 dataIp,
Jian Li1b08d652019-05-02 17:28:09 +0900820 state,
Jian Li58b33982020-07-01 19:07:02 +0900821 extNetwork,
Jian Li7709eb42019-05-08 15:58:04 +0900822 podCidr);
Jian Li49109b52019-01-22 00:17:28 +0900823 }
824
825 @Override
Jian Li58b33982020-07-01 19:07:02 +0900826 public Builder clusterName(String clusterName) {
827 this.clusterName = clusterName;
828 return this;
829 }
830
831 @Override
Jian Li49109b52019-01-22 00:17:28 +0900832 public Builder hostname(String hostname) {
833 this.hostname = hostname;
834 return this;
835 }
836
837 @Override
838 public Builder type(Type type) {
839 this.type = type;
840 return this;
841 }
842
843 @Override
Jian Li58b33982020-07-01 19:07:02 +0900844 public Builder segmentId(int segmentId) {
845 this.segmentId = segmentId;
846 return this;
847 }
848
849 @Override
850 public Builder mode(Mode mode) {
851 this.mode = mode;
852 return this;
853 }
854
855 @Override
Jian Li49109b52019-01-22 00:17:28 +0900856 public Builder intgBridge(DeviceId deviceId) {
857 this.intgBridge = deviceId;
858 return this;
859 }
860
861 @Override
Jian Libf562c22019-04-15 18:07:14 +0900862 public Builder extBridge(DeviceId deviceId) {
863 this.extBridge = deviceId;
864 return this;
865 }
866
867 @Override
Jian Li121ddfe2019-08-27 02:07:05 +0900868 public Builder localBridge(DeviceId deviceId) {
869 this.localBridge = deviceId;
870 return this;
871 }
872
873 @Override
Jian Li58b33982020-07-01 19:07:02 +0900874 public Builder tunBridge(DeviceId deviceId) {
875 this.tunBridge = deviceId;
876 return this;
877 }
878
879 @Override
Jian Li7709eb42019-05-08 15:58:04 +0900880 public Builder extIntf(String intf) {
881 this.extIntf = intf;
882 return this;
883 }
884
885 @Override
Jian Li49109b52019-01-22 00:17:28 +0900886 public Builder managementIp(IpAddress managementIp) {
887 this.managementIp = managementIp;
888 return this;
889 }
890
891 @Override
892 public Builder dataIp(IpAddress dataIp) {
893 this.dataIp = dataIp;
894 return this;
895 }
896
897 @Override
898 public Builder state(K8sNodeState state) {
899 this.state = state;
900 return this;
901 }
Jian Li1b08d652019-05-02 17:28:09 +0900902
903 @Override
Jian Li7709eb42019-05-08 15:58:04 +0900904 public Builder extBridgeIp(IpAddress extBridgeIp) {
905 this.extBridgeIp = extBridgeIp;
906 return this;
907 }
908
909 @Override
910 public Builder extGatewayIp(IpAddress extGatewayIp) {
911 this.extGatewayIp = extGatewayIp;
912 return this;
913 }
914
915 @Override
Jian Li1b08d652019-05-02 17:28:09 +0900916 public Builder extGatewayMac(MacAddress extGatewayMac) {
917 this.extGatewayMac = extGatewayMac;
918 return this;
919 }
Jian Li7709eb42019-05-08 15:58:04 +0900920
921 @Override
922 public Builder podCidr(String podCidr) {
923 this.podCidr = podCidr;
924 return this;
925 }
Jian Li49109b52019-01-22 00:17:28 +0900926 }
927}