blob: 79105009dff94c65bc6c73473492ea1d0c3c168b [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;
19import org.onlab.osgi.DefaultServiceDirectory;
20import org.onlab.packet.IpAddress;
Jian Li7d111d72019-04-12 13:58:44 +090021import org.onlab.packet.MacAddress;
Jian Li2778ffa2019-05-07 13:21:52 +090022import org.onosproject.net.Annotations;
Jian Li49109b52019-01-22 00:17:28 +090023import org.onosproject.net.DeviceId;
24import org.onosproject.net.Port;
25import org.onosproject.net.PortNumber;
26import org.onosproject.net.device.DeviceService;
27
28import java.util.Objects;
29
30import static com.google.common.base.Preconditions.checkArgument;
Jian Lieb488ea2019-04-16 01:50:02 +090031import static org.onosproject.k8snode.api.Constants.EXTERNAL_BRIDGE;
Jian Li49109b52019-01-22 00:17:28 +090032import static org.onosproject.k8snode.api.Constants.GENEVE_TUNNEL;
33import static org.onosproject.k8snode.api.Constants.GRE_TUNNEL;
Jian Li4aa17642019-01-30 00:01:11 +090034import static org.onosproject.k8snode.api.Constants.INTEGRATION_BRIDGE;
Jian Lieb488ea2019-04-16 01:50:02 +090035import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_EXTERNAL_BRIDGE;
36import static org.onosproject.k8snode.api.Constants.PHYSICAL_EXTERNAL_BRIDGE;
Jian Li49109b52019-01-22 00:17:28 +090037import static org.onosproject.k8snode.api.Constants.VXLAN_TUNNEL;
38import static org.onosproject.net.AnnotationKeys.PORT_NAME;
39
40/**
41 * Representation of a kubernetes node.
42 */
43public class DefaultK8sNode implements K8sNode {
44
Jian Li2778ffa2019-05-07 13:21:52 +090045 private static final String PORT_MAC = "portMac";
Jian Li7d111d72019-04-12 13:58:44 +090046
Jian Li49109b52019-01-22 00:17:28 +090047 private final String hostname;
48 private final Type type;
49 private final DeviceId intgBridge;
Jian Libf562c22019-04-15 18:07:14 +090050 private final DeviceId extBridge;
Jian Li49109b52019-01-22 00:17:28 +090051 private final IpAddress managementIp;
52 private final IpAddress dataIp;
53 private final K8sNodeState state;
Jian Li0c632722019-05-08 15:58:04 +090054 private final String extIntf;
55 private final IpAddress extBridgeIp;
56 private final IpAddress extGatewayIp;
Jian Li1b08d652019-05-02 17:28:09 +090057 private final MacAddress extGatewayMac;
Jian Li0c632722019-05-08 15:58:04 +090058 private final String podCidr;
Jian Li49109b52019-01-22 00:17:28 +090059
60 private static final String NOT_NULL_MSG = "Node % cannot be null";
61
62 private static final String OVSDB = "ovsdb:";
63
64 /**
65 * A default constructor of kubernetes Node.
66 *
67 * @param hostname hostname
68 * @param type node type
69 * @param intgBridge integration bridge
Jian Libf562c22019-04-15 18:07:14 +090070 * @param extBridge external bridge
Jian Li0c632722019-05-08 15:58:04 +090071 * @param extIntf external interface
Jian Li49109b52019-01-22 00:17:28 +090072 * @param managementIp management IP address
73 * @param dataIp data IP address
74 * @param state node state
Jian Li0c632722019-05-08 15:58:04 +090075 * @param extBridgeIp external bridge IP address
76 * @param extGatewayIp external gateway IP address
Jian Li1b08d652019-05-02 17:28:09 +090077 * @param extGatewayMac external gateway MAC address
Jian Li0c632722019-05-08 15:58:04 +090078 * @param podCidr POD CIDR
Jian Li49109b52019-01-22 00:17:28 +090079 */
80 protected DefaultK8sNode(String hostname, Type type, DeviceId intgBridge,
Jian Li0c632722019-05-08 15:58:04 +090081 DeviceId extBridge, String extIntf,
82 IpAddress managementIp, IpAddress dataIp,
83 K8sNodeState state, IpAddress extBridgeIp,
84 IpAddress extGatewayIp, MacAddress extGatewayMac,
85 String podCidr) {
Jian Li49109b52019-01-22 00:17:28 +090086 this.hostname = hostname;
87 this.type = type;
88 this.intgBridge = intgBridge;
Jian Libf562c22019-04-15 18:07:14 +090089 this.extBridge = extBridge;
Jian Li0c632722019-05-08 15:58:04 +090090 this.extIntf = extIntf;
Jian Li49109b52019-01-22 00:17:28 +090091 this.managementIp = managementIp;
92 this.dataIp = dataIp;
93 this.state = state;
Jian Li0c632722019-05-08 15:58:04 +090094 this.extBridgeIp = extBridgeIp;
95 this.extGatewayIp = extGatewayIp;
Jian Li1b08d652019-05-02 17:28:09 +090096 this.extGatewayMac = extGatewayMac;
Jian Li0c632722019-05-08 15:58:04 +090097 this.podCidr = podCidr;
Jian Li49109b52019-01-22 00:17:28 +090098 }
99
100 @Override
101 public String hostname() {
102 return hostname;
103 }
104
105 @Override
106 public Type type() {
107 return type;
108 }
109
110 @Override
111 public DeviceId ovsdb() {
112 return DeviceId.deviceId(OVSDB + managementIp().toString());
113 }
114
115 @Override
116 public DeviceId intgBridge() {
117 return intgBridge;
118 }
119
120 @Override
Jian Libf562c22019-04-15 18:07:14 +0900121 public DeviceId extBridge() {
122 return extBridge;
123 }
124
125 @Override
Jian Li0c632722019-05-08 15:58:04 +0900126 public String extIntf() {
127 return extIntf;
128 }
129
130 @Override
Jian Li1cee9882019-02-13 11:25:25 +0900131 public K8sNode updateIntgBridge(DeviceId deviceId) {
132 return new Builder()
133 .hostname(hostname)
134 .type(type)
135 .intgBridge(deviceId)
Jian Libf562c22019-04-15 18:07:14 +0900136 .extBridge(extBridge)
Jian Li0c632722019-05-08 15:58:04 +0900137 .extIntf(extIntf)
Jian Libf562c22019-04-15 18:07:14 +0900138 .managementIp(managementIp)
139 .dataIp(dataIp)
140 .state(state)
Jian Li0c632722019-05-08 15:58:04 +0900141 .extBridgeIp(extBridgeIp)
142 .extGatewayIp(extGatewayIp)
Jian Li1b08d652019-05-02 17:28:09 +0900143 .extGatewayMac(extGatewayMac)
Jian Li0c632722019-05-08 15:58:04 +0900144 .podCidr(podCidr)
Jian Libf562c22019-04-15 18:07:14 +0900145 .build();
146 }
147
148 @Override
149 public K8sNode updateExtBridge(DeviceId deviceId) {
150 return new Builder()
151 .hostname(hostname)
152 .type(type)
153 .intgBridge(intgBridge)
154 .extBridge(deviceId)
Jian Li0c632722019-05-08 15:58:04 +0900155 .extIntf(extIntf)
Jian Li1cee9882019-02-13 11:25:25 +0900156 .managementIp(managementIp)
157 .dataIp(dataIp)
158 .state(state)
Jian Li0c632722019-05-08 15:58:04 +0900159 .extBridgeIp(extBridgeIp)
160 .extGatewayIp(extGatewayIp)
Jian Li1b08d652019-05-02 17:28:09 +0900161 .extGatewayMac(extGatewayMac)
Jian Li0c632722019-05-08 15:58:04 +0900162 .podCidr(podCidr)
Jian Li1cee9882019-02-13 11:25:25 +0900163 .build();
164 }
165
166 @Override
Jian Li49109b52019-01-22 00:17:28 +0900167 public IpAddress managementIp() {
168 return managementIp;
169 }
170
171 @Override
172 public IpAddress dataIp() {
173 return dataIp;
174 }
175
176 @Override
177 public K8sNodeState state() {
178 return state;
179 }
180
181 @Override
Jian Li0c632722019-05-08 15:58:04 +0900182 public String podCidr() {
183 return podCidr;
184 }
185
186 @Override
Jian Li49109b52019-01-22 00:17:28 +0900187 public K8sNode updateState(K8sNodeState newState) {
188 return new Builder()
189 .hostname(hostname)
190 .type(type)
191 .intgBridge(intgBridge)
Jian Li0c632722019-05-08 15:58:04 +0900192 .extBridge(extBridge)
193 .extIntf(extIntf)
Jian Li49109b52019-01-22 00:17:28 +0900194 .managementIp(managementIp)
195 .dataIp(dataIp)
196 .state(newState)
Jian Li0c632722019-05-08 15:58:04 +0900197 .extBridgeIp(extBridgeIp)
198 .extGatewayIp(extGatewayIp)
Jian Li1b08d652019-05-02 17:28:09 +0900199 .extGatewayMac(extGatewayMac)
Jian Li0c632722019-05-08 15:58:04 +0900200 .podCidr(podCidr)
Jian Li49109b52019-01-22 00:17:28 +0900201 .build();
202 }
203
204 @Override
Jian Li1b08d652019-05-02 17:28:09 +0900205 public K8sNode updateExtGatewayMac(MacAddress newMac) {
206 return new Builder()
207 .hostname(hostname)
208 .type(type)
209 .intgBridge(intgBridge)
Jian Li0c632722019-05-08 15:58:04 +0900210 .extBridge(extBridge)
211 .extIntf(extIntf)
Jian Li1b08d652019-05-02 17:28:09 +0900212 .managementIp(managementIp)
213 .dataIp(dataIp)
214 .state(state)
Jian Li0c632722019-05-08 15:58:04 +0900215 .extBridgeIp(extBridgeIp)
216 .extGatewayIp(extGatewayIp)
Jian Li1b08d652019-05-02 17:28:09 +0900217 .extGatewayMac(newMac)
Jian Li0c632722019-05-08 15:58:04 +0900218 .podCidr(podCidr)
Jian Li1b08d652019-05-02 17:28:09 +0900219 .build();
Jian Li1b08d652019-05-02 17:28:09 +0900220 }
221
222 @Override
Jian Li49109b52019-01-22 00:17:28 +0900223 public PortNumber grePortNum() {
224 return tunnelPortNum(GRE_TUNNEL);
225 }
226
227 @Override
228 public PortNumber vxlanPortNum() {
229 return tunnelPortNum(VXLAN_TUNNEL);
230 }
231
232 @Override
233 public PortNumber genevePortNum() {
234 return tunnelPortNum(GENEVE_TUNNEL);
235 }
236
237 @Override
Jian Lieb488ea2019-04-16 01:50:02 +0900238 public PortNumber intgBridgePortNum() {
Jian Li2778ffa2019-05-07 13:21:52 +0900239 return portNumber(intgBridge, INTEGRATION_BRIDGE);
Jian Lieb488ea2019-04-16 01:50:02 +0900240 }
241
242 @Override
243 public PortNumber intgToExtPatchPortNum() {
244 return portNumber(intgBridge, INTEGRATION_TO_EXTERNAL_BRIDGE);
245 }
246
247 @Override
248 public PortNumber extToIntgPatchPortNum() {
249 return portNumber(extBridge, PHYSICAL_EXTERNAL_BRIDGE);
250 }
251
252 @Override
253 public PortNumber extBridgePortNum() {
Jian Li0c632722019-05-08 15:58:04 +0900254 if (this.extIntf == null) {
Jian Lieb488ea2019-04-16 01:50:02 +0900255 return null;
256 }
257
Jian Li0c632722019-05-08 15:58:04 +0900258 return portNumber(extBridge, this.extIntf);
Jian Lieb488ea2019-04-16 01:50:02 +0900259 }
260
261 @Override
Jian Li2778ffa2019-05-07 13:21:52 +0900262 public MacAddress intgBridgeMac() {
263 return macAddress(intgBridge, INTEGRATION_BRIDGE);
264 }
265
266 @Override
267 public IpAddress extBridgeIp() {
Jian Li0c632722019-05-08 15:58:04 +0900268 return extBridgeIp;
Jian Li2778ffa2019-05-07 13:21:52 +0900269 }
270
271 @Override
272 public MacAddress extBridgeMac() {
273 return macAddress(extBridge, EXTERNAL_BRIDGE);
274 }
275
276 @Override
277 public IpAddress extGatewayIp() {
Jian Li0c632722019-05-08 15:58:04 +0900278 return extGatewayIp;
Jian Li2778ffa2019-05-07 13:21:52 +0900279 }
280
281 @Override
282 public MacAddress extGatewayMac() {
283 return extGatewayMac;
284 }
285
286 @Override
Jian Li49109b52019-01-22 00:17:28 +0900287 public boolean equals(Object obj) {
288 if (this == obj) {
289 return true;
290 }
291
292 if (obj instanceof DefaultK8sNode) {
293 DefaultK8sNode that = (DefaultK8sNode) obj;
294
295 return hostname.equals(that.hostname) &&
296 type == that.type &&
297 intgBridge.equals(that.intgBridge) &&
Jian Libf562c22019-04-15 18:07:14 +0900298 extBridge.equals(that.extBridge) &&
Jian Li0c632722019-05-08 15:58:04 +0900299 extIntf.equals(that.extIntf) &&
Jian Li49109b52019-01-22 00:17:28 +0900300 managementIp.equals(that.managementIp) &&
301 dataIp.equals(that.dataIp) &&
Jian Li0c632722019-05-08 15:58:04 +0900302 extBridgeIp.equals(that.extBridgeIp) &&
303 extGatewayIp.equals(that.extGatewayIp) &&
304 podCidr.equals(that.podCidr) &&
Jian Li49109b52019-01-22 00:17:28 +0900305 state == that.state;
306 }
307
308 return false;
309 }
310
311 @Override
312 public int hashCode() {
Jian Li0c632722019-05-08 15:58:04 +0900313 return Objects.hash(hostname, type, intgBridge, extBridge, extIntf,
314 managementIp, dataIp, state, extBridgeIp,
315 extGatewayIp, extGatewayMac, podCidr);
Jian Li49109b52019-01-22 00:17:28 +0900316 }
317
318 @Override
319 public String toString() {
320 return MoreObjects.toStringHelper(this)
321 .add("hostname", hostname)
322 .add("type", type)
323 .add("intgBridge", intgBridge)
Jian Libf562c22019-04-15 18:07:14 +0900324 .add("extBridge", extBridge)
Jian Li0c632722019-05-08 15:58:04 +0900325 .add("extIntf", extIntf)
Jian Li49109b52019-01-22 00:17:28 +0900326 .add("managementIp", managementIp)
327 .add("dataIp", dataIp)
328 .add("state", state)
Jian Li0c632722019-05-08 15:58:04 +0900329 .add("extBridgeIp", extBridgeIp)
330 .add("extGatewayIp", extGatewayIp)
Jian Li1b08d652019-05-02 17:28:09 +0900331 .add("extGatewayMac", extGatewayMac)
Jian Li0c632722019-05-08 15:58:04 +0900332 .add("podCidr", podCidr)
Jian Li49109b52019-01-22 00:17:28 +0900333 .toString();
334 }
335
336 private PortNumber tunnelPortNum(String tunnelType) {
337 if (dataIp == null) {
338 return null;
339 }
Jian Lieb488ea2019-04-16 01:50:02 +0900340
341 return portNumber(intgBridge, tunnelType);
342 }
343
Jian Li2778ffa2019-05-07 13:21:52 +0900344 private MacAddress macAddress(DeviceId deviceId, String portName) {
345 Port port = port(deviceId, portName);
346 Annotations annots = port.annotations();
347 return annots != null ? MacAddress.valueOf(annots.value(PORT_MAC)) : null;
348 }
349
Jian Lieb488ea2019-04-16 01:50:02 +0900350 private PortNumber portNumber(DeviceId deviceId, String portName) {
Jian Li2778ffa2019-05-07 13:21:52 +0900351 Port port = port(deviceId, portName);
352 return port != null ? port.number() : null;
353 }
354
355 private Port port(DeviceId deviceId, String portName) {
Jian Li49109b52019-01-22 00:17:28 +0900356 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
Jian Li2778ffa2019-05-07 13:21:52 +0900357 return deviceService.getPorts(deviceId).stream()
Jian Li49109b52019-01-22 00:17:28 +0900358 .filter(p -> p.isEnabled() &&
Jian Lieb488ea2019-04-16 01:50:02 +0900359 Objects.equals(p.annotations().value(PORT_NAME), portName))
Jian Li49109b52019-01-22 00:17:28 +0900360 .findAny().orElse(null);
Jian Li49109b52019-01-22 00:17:28 +0900361 }
362
363 /**
364 * Returns new builder instance.
365 *
366 * @return kubernetes node builder
367 */
368 public static Builder builder() {
369 return new Builder();
370 }
371
372 /**
373 * Returns new builder instance with the given node as a default value.
374 *
375 * @param node kubernetes node
376 * @return kubernetes node builder
377 */
378 public static Builder from(K8sNode node) {
379 return new Builder()
380 .hostname(node.hostname())
381 .type(node.type())
382 .intgBridge(node.intgBridge())
Jian Libf562c22019-04-15 18:07:14 +0900383 .extBridge(node.extBridge())
Jian Li0c632722019-05-08 15:58:04 +0900384 .extIntf(node.extIntf())
Jian Li49109b52019-01-22 00:17:28 +0900385 .managementIp(node.managementIp())
386 .dataIp(node.dataIp())
Jian Li1b08d652019-05-02 17:28:09 +0900387 .state(node.state())
Jian Li0c632722019-05-08 15:58:04 +0900388 .extBridgeIp(node.extBridgeIp())
389 .extGatewayIp(node.extGatewayIp())
390 .extGatewayMac(node.extGatewayMac())
391 .podCidr(node.podCidr());
Jian Li49109b52019-01-22 00:17:28 +0900392 }
393
394 public static final class Builder implements K8sNode.Builder {
395
396 private String hostname;
397 private Type type;
398 private DeviceId intgBridge;
Jian Libf562c22019-04-15 18:07:14 +0900399 private DeviceId extBridge;
Jian Li49109b52019-01-22 00:17:28 +0900400 private IpAddress managementIp;
401 private IpAddress dataIp;
402 private K8sNodeState state;
Jian Li3defa842019-02-12 00:31:35 +0900403 private K8sApiConfig apiConfig;
Jian Li0c632722019-05-08 15:58:04 +0900404 private String extIntf;
405 private IpAddress extBridgeIp;
406 private IpAddress extGatewayIp;
Jian Li1b08d652019-05-02 17:28:09 +0900407 private MacAddress extGatewayMac;
Jian Li0c632722019-05-08 15:58:04 +0900408 private String podCidr;
Jian Li49109b52019-01-22 00:17:28 +0900409
410 // private constructor not intended to use from external
411 private Builder() {
412 }
413
414 @Override
415 public K8sNode build() {
416 checkArgument(hostname != null, NOT_NULL_MSG, "hostname");
417 checkArgument(type != null, NOT_NULL_MSG, "type");
418 checkArgument(state != null, NOT_NULL_MSG, "state");
419 checkArgument(managementIp != null, NOT_NULL_MSG, "management IP");
420
421 return new DefaultK8sNode(hostname,
422 type,
423 intgBridge,
Jian Libf562c22019-04-15 18:07:14 +0900424 extBridge,
Jian Li0c632722019-05-08 15:58:04 +0900425 extIntf,
Jian Li49109b52019-01-22 00:17:28 +0900426 managementIp,
427 dataIp,
Jian Li1b08d652019-05-02 17:28:09 +0900428 state,
Jian Li0c632722019-05-08 15:58:04 +0900429 extBridgeIp,
430 extGatewayIp,
431 extGatewayMac,
432 podCidr);
Jian Li49109b52019-01-22 00:17:28 +0900433 }
434
435 @Override
436 public Builder hostname(String hostname) {
437 this.hostname = hostname;
438 return this;
439 }
440
441 @Override
442 public Builder type(Type type) {
443 this.type = type;
444 return this;
445 }
446
447 @Override
448 public Builder intgBridge(DeviceId deviceId) {
449 this.intgBridge = deviceId;
450 return this;
451 }
452
453 @Override
Jian Libf562c22019-04-15 18:07:14 +0900454 public Builder extBridge(DeviceId deviceId) {
455 this.extBridge = deviceId;
456 return this;
457 }
458
459 @Override
Jian Li0c632722019-05-08 15:58:04 +0900460 public Builder extIntf(String intf) {
461 this.extIntf = intf;
462 return this;
463 }
464
465 @Override
Jian Li49109b52019-01-22 00:17:28 +0900466 public Builder managementIp(IpAddress managementIp) {
467 this.managementIp = managementIp;
468 return this;
469 }
470
471 @Override
472 public Builder dataIp(IpAddress dataIp) {
473 this.dataIp = dataIp;
474 return this;
475 }
476
477 @Override
478 public Builder state(K8sNodeState state) {
479 this.state = state;
480 return this;
481 }
Jian Li1b08d652019-05-02 17:28:09 +0900482
483 @Override
Jian Li0c632722019-05-08 15:58:04 +0900484 public Builder extBridgeIp(IpAddress extBridgeIp) {
485 this.extBridgeIp = extBridgeIp;
486 return this;
487 }
488
489 @Override
490 public Builder extGatewayIp(IpAddress extGatewayIp) {
491 this.extGatewayIp = extGatewayIp;
492 return this;
493 }
494
495 @Override
Jian Li1b08d652019-05-02 17:28:09 +0900496 public Builder extGatewayMac(MacAddress extGatewayMac) {
497 this.extGatewayMac = extGatewayMac;
498 return this;
499 }
Jian Li0c632722019-05-08 15:58:04 +0900500
501 @Override
502 public Builder podCidr(String podCidr) {
503 this.podCidr = podCidr;
504 return this;
505 }
Jian Li49109b52019-01-22 00:17:28 +0900506 }
507}