blob: e0614956c1e5071e02e6707171a95b10f46ba0db [file] [log] [blame]
Jian Li9871cd52021-01-09 00:19:02 +09001/*
2 * Copyright 2021-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.kubevirtnetworking.util;
17
Jian Li260231e2021-01-13 18:05:00 +090018import com.fasterxml.jackson.databind.ObjectMapper;
Jian Lib5ab63c2021-02-03 17:54:28 +090019import com.google.common.base.Strings;
Jian Li3831f0c2021-03-12 18:03:58 +090020import com.google.common.collect.ImmutableSet;
Jian Lid5e8ea82021-01-18 00:19:31 +090021import io.fabric8.kubernetes.api.model.Pod;
Jian Li16eed162021-01-15 16:58:48 +090022import io.fabric8.kubernetes.client.ConfigBuilder;
23import io.fabric8.kubernetes.client.DefaultKubernetesClient;
24import io.fabric8.kubernetes.client.KubernetesClient;
Jian Li9871cd52021-01-09 00:19:02 +090025import org.apache.commons.lang.StringUtils;
Jian Li7bca1272021-01-14 11:30:36 +090026import org.apache.commons.net.util.SubnetUtils;
Jian Lid5e8ea82021-01-18 00:19:31 +090027import org.json.JSONArray;
28import org.json.JSONException;
29import org.json.JSONObject;
Jian Li543fe852021-02-04 17:25:01 +090030import org.onlab.osgi.DefaultServiceDirectory;
Daniel Parkb9a22022021-03-04 18:58:47 +090031import org.onlab.packet.Ip4Address;
Jian Li7bca1272021-01-14 11:30:36 +090032import org.onlab.packet.IpAddress;
Jian Lid5e8ea82021-01-18 00:19:31 +090033import org.onlab.packet.MacAddress;
Jian Li9871cd52021-01-09 00:19:02 +090034import org.onosproject.cfg.ConfigProperty;
Jian Lid5e8ea82021-01-18 00:19:31 +090035import org.onosproject.kubevirtnetworking.api.DefaultKubevirtPort;
36import org.onosproject.kubevirtnetworking.api.KubevirtNetwork;
Daniel Parke7e3d6a2021-03-10 07:49:11 +090037import org.onosproject.kubevirtnetworking.api.KubevirtNetworkService;
Jian Lid5e8ea82021-01-18 00:19:31 +090038import org.onosproject.kubevirtnetworking.api.KubevirtPort;
Daniel Parkb9a22022021-03-04 18:58:47 +090039import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
40import org.onosproject.kubevirtnetworking.api.KubevirtRouterService;
Jian Li16eed162021-01-15 16:58:48 +090041import org.onosproject.kubevirtnode.api.KubevirtApiConfig;
42import org.onosproject.kubevirtnode.api.KubevirtApiConfigService;
Jian Li543fe852021-02-04 17:25:01 +090043import org.onosproject.kubevirtnode.api.KubevirtNode;
Daniel Parkb9a22022021-03-04 18:58:47 +090044import org.onosproject.kubevirtnode.api.KubevirtNodeService;
Jian Li543fe852021-02-04 17:25:01 +090045import org.onosproject.net.DeviceId;
46import org.onosproject.net.Port;
47import org.onosproject.net.PortNumber;
48import org.onosproject.net.device.DeviceService;
Jian Li9871cd52021-01-09 00:19:02 +090049import org.slf4j.Logger;
50import org.slf4j.LoggerFactory;
51
Jian Li260231e2021-01-13 18:05:00 +090052import java.io.IOException;
Jian Li7bca1272021-01-14 11:30:36 +090053import java.util.Arrays;
54import java.util.HashSet;
Jian Li260231e2021-01-13 18:05:00 +090055import java.util.List;
Jian Lid5e8ea82021-01-18 00:19:31 +090056import java.util.Map;
Jian Li543fe852021-02-04 17:25:01 +090057import java.util.Objects;
Jian Li9871cd52021-01-09 00:19:02 +090058import java.util.Optional;
59import java.util.Set;
Jian Li7bca1272021-01-14 11:30:36 +090060import java.util.stream.Collectors;
Jian Li9871cd52021-01-09 00:19:02 +090061
Jian Li543fe852021-02-04 17:25:01 +090062import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_TO_TENANT_PREFIX;
Daniel Parkb9a22022021-03-04 18:58:47 +090063import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.GATEWAY;
Jian Li543fe852021-02-04 17:25:01 +090064import static org.onosproject.net.AnnotationKeys.PORT_NAME;
65
Jian Li9871cd52021-01-09 00:19:02 +090066/**
67 * An utility that used in KubeVirt networking app.
68 */
69public final class KubevirtNetworkingUtil {
70
71 private static final Logger log = LoggerFactory.getLogger(KubevirtNetworkingUtil.class);
72
73 private static final int PORT_NAME_MAX_LENGTH = 15;
Jian Li16eed162021-01-15 16:58:48 +090074 private static final String COLON_SLASH = "://";
75 private static final String COLON = ":";
Jian Lib5ab63c2021-02-03 17:54:28 +090076 private static final String OF_PREFIX = "of:";
Jian Li9871cd52021-01-09 00:19:02 +090077
Jian Lid5e8ea82021-01-18 00:19:31 +090078 private static final String NETWORK_STATUS_KEY = "k8s.v1.cni.cncf.io/network-status";
79 private static final String NAME = "name";
80 private static final String NETWORK_PREFIX = "default/";
81 private static final String MAC = "mac";
82 private static final String IPS = "ips";
Daniel Parkcc8e7462021-03-09 13:37:42 +090083 private static final String BR_INT = "br-int";
Jian Lid5e8ea82021-01-18 00:19:31 +090084
Jian Li9871cd52021-01-09 00:19:02 +090085 /**
86 * Prevents object installation from external.
87 */
88 private KubevirtNetworkingUtil() {
89 }
90
91 /**
92 * Obtains the boolean property value with specified property key name.
93 *
Daniel Parkb9a22022021-03-04 18:58:47 +090094 * @param properties a collection of properties
95 * @param name key name
Jian Li9871cd52021-01-09 00:19:02 +090096 * @return mapping value
97 */
98 public static boolean getPropertyValueAsBoolean(Set<ConfigProperty> properties,
99 String name) {
100 Optional<ConfigProperty> property =
101 properties.stream().filter(p -> p.name().equals(name)).findFirst();
102
103 return property.map(ConfigProperty::asBoolean).orElse(false);
104 }
105
106 /**
107 * Re-structures the OVS port name.
108 * The length of OVS port name should be not large than 15.
109 *
Daniel Parkb9a22022021-03-04 18:58:47 +0900110 * @param portName original port name
Jian Li9871cd52021-01-09 00:19:02 +0900111 * @return re-structured OVS port name
112 */
113 public static String structurePortName(String portName) {
114
115 // The size of OVS port name should not be larger than 15
116 if (portName.length() > PORT_NAME_MAX_LENGTH) {
117 return StringUtils.substring(portName, 0, PORT_NAME_MAX_LENGTH);
118 }
119
120 return portName;
121 }
Jian Li260231e2021-01-13 18:05:00 +0900122
123 /**
124 * Generates string format based on the given string length list.
125 *
126 * @param stringLengths a list of string lengths
127 * @return string format (e.g., %-28s%-15s%-24s%-20s%-15s)
128 */
129 public static String genFormatString(List<Integer> stringLengths) {
130 StringBuilder fsb = new StringBuilder();
131 stringLengths.forEach(length -> {
132 fsb.append("%-");
133 fsb.append(length);
134 fsb.append("s");
135 });
136 return fsb.toString();
137 }
138
139 /**
Jian Lib5ab63c2021-02-03 17:54:28 +0900140 * Auto generates DPID from the given name.
141 *
142 * @param name name
143 * @return auto generated DPID
144 */
145 public static String genDpidFromName(String name) {
146 if (name != null) {
147 String hexString = Integer.toHexString(name.hashCode());
148 return OF_PREFIX + Strings.padStart(hexString, 16, '0');
149 }
150
151 return null;
152 }
153
154 /**
Jian Li260231e2021-01-13 18:05:00 +0900155 * Prints out the JSON string in pretty format.
156 *
Daniel Parkb9a22022021-03-04 18:58:47 +0900157 * @param mapper Object mapper
158 * @param jsonString JSON string
Jian Li260231e2021-01-13 18:05:00 +0900159 * @return pretty formatted JSON string
160 */
161 public static String prettyJson(ObjectMapper mapper, String jsonString) {
162 try {
163 Object jsonObject = mapper.readValue(jsonString, Object.class);
164 return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject);
165 } catch (IOException e) {
166 log.debug("Json string parsing exception caused by {}", e);
167 }
168 return null;
169 }
Jian Li7bca1272021-01-14 11:30:36 +0900170
171 /**
172 * Obtains valid IP addresses of the given subnet.
173 *
174 * @param cidr CIDR
175 * @return set of IP addresses
176 */
177 public static Set<IpAddress> getSubnetIps(String cidr) {
178 SubnetUtils utils = new SubnetUtils(cidr);
179 utils.setInclusiveHostCount(false);
180 SubnetUtils.SubnetInfo info = utils.getInfo();
181 Set<String> allAddresses =
182 new HashSet<>(Arrays.asList(info.getAllAddresses()));
183
184 if (allAddresses.size() > 2) {
185 allAddresses.remove(info.getLowAddress());
186 allAddresses.remove(info.getHighAddress());
187 }
188
189 return allAddresses.stream()
190 .map(IpAddress::valueOf).collect(Collectors.toSet());
191 }
192
193 /**
194 * Calculate the broadcast address from given IP address and subnet prefix length.
195 *
Daniel Parkb9a22022021-03-04 18:58:47 +0900196 * @param ipAddr IP address
197 * @param prefixLength subnet prefix length
Jian Li7bca1272021-01-14 11:30:36 +0900198 * @return broadcast address
199 */
200 public static String getBroadcastAddr(String ipAddr, int prefixLength) {
201 String subnet = ipAddr + "/" + prefixLength;
202 SubnetUtils utils = new SubnetUtils(subnet);
203 return utils.getInfo().getBroadcastAddress();
204 }
Daniel Parkb9a22022021-03-04 18:58:47 +0900205
Jian Li16eed162021-01-15 16:58:48 +0900206 /**
207 * Generates endpoint URL by referring to scheme, ipAddress and port.
208 *
Daniel Parkb9a22022021-03-04 18:58:47 +0900209 * @param scheme scheme
210 * @param ipAddress IP address
211 * @param port port number
Jian Li16eed162021-01-15 16:58:48 +0900212 * @return generated endpoint URL
213 */
214 public static String endpoint(KubevirtApiConfig.Scheme scheme, IpAddress ipAddress, int port) {
215 StringBuilder endpoint = new StringBuilder();
216 String protocol = org.apache.commons.lang3.StringUtils.lowerCase(scheme.name());
217
218 endpoint.append(protocol);
219 endpoint.append(COLON_SLASH);
220 endpoint.append(ipAddress.toString());
221 endpoint.append(COLON);
222 endpoint.append(port);
223
224 return endpoint.toString();
225 }
226
227 /**
228 * Generates endpoint URL by referring to scheme, ipAddress and port.
229 *
Daniel Parkb9a22022021-03-04 18:58:47 +0900230 * @param apiConfig kubernetes API config
Jian Li16eed162021-01-15 16:58:48 +0900231 * @return generated endpoint URL
232 */
233 public static String endpoint(KubevirtApiConfig apiConfig) {
234 return endpoint(apiConfig.scheme(), apiConfig.ipAddress(), apiConfig.port());
235 }
236
237 /**
238 * Obtains workable kubernetes client.
239 *
240 * @param config kubernetes API config
241 * @return kubernetes client
242 */
243 public static KubernetesClient k8sClient(KubevirtApiConfig config) {
244 if (config == null) {
245 log.warn("Kubernetes API server config is empty.");
246 return null;
247 }
248
249 String endpoint = endpoint(config);
250
251 ConfigBuilder configBuilder = new ConfigBuilder().withMasterUrl(endpoint);
252
253 if (config.scheme() == KubevirtApiConfig.Scheme.HTTPS) {
254 configBuilder.withTrustCerts(true)
Jian Li16eed162021-01-15 16:58:48 +0900255 .withCaCertData(config.caCertData())
256 .withClientCertData(config.clientCertData())
257 .withClientKeyData(config.clientKeyData());
258 }
259
260 return new DefaultKubernetesClient(configBuilder.build());
261 }
262
263 /**
264 * Obtains workable kubernetes client.
265 *
266 * @param service kubernetes API service
267 * @return kubernetes client
268 */
269 public static KubernetesClient k8sClient(KubevirtApiConfigService service) {
270 KubevirtApiConfig config = service.apiConfig();
271 if (config == null) {
272 log.error("Failed to find valid kubernetes API configuration.");
273 return null;
274 }
275
276 KubernetesClient client = k8sClient(config);
277
278 if (client == null) {
279 log.error("Failed to connect to kubernetes API server.");
280 return null;
281 }
282
283 return client;
284 }
Jian Lid5e8ea82021-01-18 00:19:31 +0900285
286 /**
Jian Lib5ab63c2021-02-03 17:54:28 +0900287 * Obtains the hex string of the given segment ID with fixed padding.
288 *
289 * @param segIdStr segment identifier string
290 * @return hex string with padding
291 */
292 public static String segmentIdHex(String segIdStr) {
293 int segId = Integer.parseInt(segIdStr);
294 return String.format("%06x", segId).toLowerCase();
295 }
296
297 /**
Jian Li543fe852021-02-04 17:25:01 +0900298 * Obtains the tunnel port number with the given network and node.
299 *
300 * @param network kubevirt network
Daniel Parkb9a22022021-03-04 18:58:47 +0900301 * @param node kubevirt node
Jian Li543fe852021-02-04 17:25:01 +0900302 * @return tunnel port number
303 */
304 public static PortNumber tunnelPort(KubevirtNetwork network, KubevirtNode node) {
305 switch (network.type()) {
306 case VXLAN:
307 return node.vxlanPort();
308 case GRE:
309 return node.grePort();
310 case GENEVE:
311 return node.genevePort();
312 default:
313 break;
314 }
315 return null;
316 }
317
318 /**
Jian Lid5e8ea82021-01-18 00:19:31 +0900319 * Obtains the kubevirt port from kubevirt POD.
320 *
Daniel Parke7e3d6a2021-03-10 07:49:11 +0900321 * @param nodeService kubevirt node service
Jian Lid5e8ea82021-01-18 00:19:31 +0900322 * @param networks set of existing kubevirt networks
Daniel Parkb9a22022021-03-04 18:58:47 +0900323 * @param pod kubevirt POD
Jian Li3831f0c2021-03-12 18:03:58 +0900324 * @return kubevirt ports attached to the POD
Jian Lid5e8ea82021-01-18 00:19:31 +0900325 */
Daniel Parke7e3d6a2021-03-10 07:49:11 +0900326 public static Set<KubevirtPort> getPorts(KubevirtNodeService nodeService, Set<KubevirtNetwork> networks, Pod pod) {
Jian Lid5e8ea82021-01-18 00:19:31 +0900327 try {
328 Map<String, String> annots = pod.getMetadata().getAnnotations();
Jian Li840156c2021-01-21 20:30:52 +0900329 if (annots == null) {
Jian Li3831f0c2021-03-12 18:03:58 +0900330 return ImmutableSet.of();
Jian Li840156c2021-01-21 20:30:52 +0900331 }
332
Jian Li2417ab72021-02-02 17:35:12 +0900333 if (!annots.containsKey(NETWORK_STATUS_KEY)) {
Jian Li3831f0c2021-03-12 18:03:58 +0900334 return ImmutableSet.of();
Jian Li2417ab72021-02-02 17:35:12 +0900335 }
336
Jian Lid5e8ea82021-01-18 00:19:31 +0900337 String networkStatusStr = annots.get(NETWORK_STATUS_KEY);
338
339 if (networkStatusStr == null) {
Jian Li3831f0c2021-03-12 18:03:58 +0900340 return ImmutableSet.of();
Jian Lid5e8ea82021-01-18 00:19:31 +0900341 }
Daniel Parke7e3d6a2021-03-10 07:49:11 +0900342 KubevirtPort.Builder builder = DefaultKubevirtPort.builder();
343
344 KubevirtNode node = nodeService.node(pod.getSpec().getNodeName());
345 if (node != null) {
346 builder.deviceId(node.intgBridge());
347 }
Jian Lid5e8ea82021-01-18 00:19:31 +0900348
349 JSONArray networkStatus = new JSONArray(networkStatusStr);
Jian Li3831f0c2021-03-12 18:03:58 +0900350 Set<KubevirtPort> ports = new HashSet<>();
Jian Lid5e8ea82021-01-18 00:19:31 +0900351
352 for (int i = 0; i < networkStatus.length(); i++) {
353 JSONObject object = networkStatus.getJSONObject(i);
354 String name = object.getString(NAME);
355 KubevirtNetwork network = networks.stream()
356 .filter(n -> (NETWORK_PREFIX + n.name()).equals(name))
357 .findAny().orElse(null);
358 if (network != null) {
359 String mac = object.getString(MAC);
360
Daniel Parke7e3d6a2021-03-10 07:49:11 +0900361 builder.macAddress(MacAddress.valueOf(mac))
Jian Lid5e8ea82021-01-18 00:19:31 +0900362 .networkId(network.networkId());
363
364 if (object.has(IPS)) {
365 JSONArray ips = object.getJSONArray(IPS);
366 String ip = (String) ips.get(0);
367 builder.ipAddress(IpAddress.valueOf(ip));
368 }
369
Jian Li3831f0c2021-03-12 18:03:58 +0900370 ports.add(builder.build());
Jian Lid5e8ea82021-01-18 00:19:31 +0900371 }
372 }
373
Jian Li3831f0c2021-03-12 18:03:58 +0900374 return ports;
375
Jian Lid5e8ea82021-01-18 00:19:31 +0900376 } catch (JSONException e) {
377 log.error("Failed to parse network status object", e);
378 }
379
Jian Li3831f0c2021-03-12 18:03:58 +0900380 return ImmutableSet.of();
Jian Lid5e8ea82021-01-18 00:19:31 +0900381 }
Jian Li543fe852021-02-04 17:25:01 +0900382
383 /**
384 * Obtains the tunnel bridge to tenant bridge patch port number.
385 *
Daniel Parkb9a22022021-03-04 18:58:47 +0900386 * @param node kubevirt node
Jian Li543fe852021-02-04 17:25:01 +0900387 * @param network kubevirt network
388 * @return patch port number
389 */
390 public static PortNumber tunnelToTenantPort(KubevirtNode node, KubevirtNetwork network) {
391 if (network.segmentId() == null) {
392 return null;
393 }
394
395 if (node.tunBridge() == null) {
396 return null;
397 }
398
399 String tunToTenantPortName = TUNNEL_TO_TENANT_PREFIX + segmentIdHex(network.segmentId());
400 return portNumber(node.tunBridge(), tunToTenantPortName);
401 }
402
403 /**
404 * Obtains the tunnel port number of the given node.
405 *
Daniel Parkb9a22022021-03-04 18:58:47 +0900406 * @param node kubevirt node
Jian Li543fe852021-02-04 17:25:01 +0900407 * @param network kubevirt network
408 * @return tunnel port number
409 */
410 public static PortNumber tunnelPort(KubevirtNode node, KubevirtNetwork network) {
411 if (network.segmentId() == null) {
412 return null;
413 }
414
415 if (node.tunBridge() == null) {
416 return null;
417 }
418
419 switch (network.type()) {
420 case VXLAN:
421 return node.vxlanPort();
422 case GRE:
423 return node.grePort();
424 case GENEVE:
425 return node.genevePort();
426 case FLAT:
Jian Li81b1aab2021-02-17 20:42:15 +0900427 case VLAN:
Jian Li543fe852021-02-04 17:25:01 +0900428 default:
429 // do nothing
430 return null;
431 }
432 }
433
Jian Li7eb20782021-02-27 01:10:50 +0900434 public static String parseResourceName(String resource) {
435 try {
436 JSONObject json = new JSONObject(resource);
437 return json.getJSONObject("metadata").getString("name");
438 } catch (JSONException e) {
439 log.error("");
440 }
441 return "";
442 }
443
Daniel Parke7e3d6a2021-03-10 07:49:11 +0900444 public static PortNumber portNumber(DeviceId deviceId, String portName) {
Jian Li543fe852021-02-04 17:25:01 +0900445 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
446 Port port = deviceService.getPorts(deviceId).stream()
447 .filter(p -> p.isEnabled() &&
448 Objects.equals(p.annotations().value(PORT_NAME), portName))
449 .findAny().orElse(null);
450 return port != null ? port.number() : null;
451 }
452
Daniel Parkb9a22022021-03-04 18:58:47 +0900453 /**
454 * Returns the gateway node for the specified kubevirt router.
455 * Among gateways, only one gateway would act as a gateway per perter.
456 * Currently gateway node is selected based on modulo operation with router hashcode.
457 *
458 * @param nodeService kubevirt node service
459 * @param router kubevirt router
460 * @return elected gateway node
461 */
462 public static KubevirtNode gatewayNodeForSpecifiedRouter(KubevirtNodeService nodeService,
463 KubevirtRouter router) {
464 //TODO: enhance election logic for a better load balancing
465
466 int numOfGateways = nodeService.completeNodes(GATEWAY).size();
467 if (numOfGateways == 0) {
468 return null;
469 }
470 return (KubevirtNode) nodeService.completeNodes(GATEWAY).toArray()[router.hashCode() % numOfGateways];
471 }
472
473 /**
474 * Returns the mac address of the br-int port of specified device.
475 *
476 * @param deviceService device service
477 * @param deviceId device Id
478 * @return mac address of the br-int port
479 */
Daniel Parke7e3d6a2021-03-10 07:49:11 +0900480
481 /**
482 * Returns the mac address of the router.
483 *
484 * @param router kubevirt router
485 * @return macc address of the router
486 */
487 public static MacAddress getRouterMacAddress(KubevirtRouter router) {
488 if (router.mac() == null) {
489 log.warn("Failed to get mac address of router {}", router.name());
490 }
491
492 return router.mac();
Daniel Parkb9a22022021-03-04 18:58:47 +0900493 }
494
495 /**
496 * Returns the snat ip address with specified router.
497 *
498 * @param routerService router service
499 * @param internalNetworkId internal network id which is associated with the router
500 * @return snat ip address if exist, null otherwise
501 */
502 public static IpAddress getRouterSnatIpAddress(KubevirtRouterService routerService,
503 String internalNetworkId) {
504 KubevirtRouter router = routerService.routers().stream()
505 .filter(r -> r.internal().contains(internalNetworkId))
506 .findAny().orElse(null);
507
508 if (router == null) {
509 return null;
510 }
511
512 String routerSnatIp = router.external().keySet().stream().findAny().orElse(null);
513
514 if (routerSnatIp == null) {
515 return null;
516 }
517
518 return Ip4Address.valueOf(routerSnatIp);
519 }
Daniel Parkcc8e7462021-03-09 13:37:42 +0900520
521 /**
522 * Returns the kubevirt router with specified kubevirt port.
523 *
524 * @param routerService kubevirt router service
525 * @param kubevirtPort kubevirt port
526 * @return kubevirt router
527 */
528 public static KubevirtRouter getRouterForKubevirtPort(KubevirtRouterService routerService,
529 KubevirtPort kubevirtPort) {
530 if (kubevirtPort.ipAddress() != null) {
531 return routerService.routers().stream()
532 .filter(r -> r.internal().contains(kubevirtPort.networkId()))
533 .findAny().orElse(null);
534 }
535 return null;
536 }
537
538 /**
539 * Returns the kubevirt router with specified kubevirt network.
540 *
541 * @param routerService kubevirt router service
542 * @param kubevirtNetwork kubevirt network
543 * @return kubevirt router
544 */
545 public static KubevirtRouter getRouterForKubevirtNetwork(KubevirtRouterService routerService,
546 KubevirtNetwork kubevirtNetwork) {
547 return routerService.routers().stream()
548 .filter(router -> router.internal().contains(kubevirtNetwork.networkId()))
549 .findAny().orElse(null);
550 }
Daniel Parke7e3d6a2021-03-10 07:49:11 +0900551
552 /**
553 * Returns the external patch port number with specified gateway.
554 *
555 * @param deviceService device service
556 * @param gatewayNode gateawy node
557 * @return external patch port number
558 */
559 public static PortNumber externalPatchPortNum(DeviceService deviceService, KubevirtNode gatewayNode) {
560 Port port = deviceService.getPorts(gatewayNode.intgBridge()).stream()
561 .filter(p -> p.isEnabled() &&
562 Objects.equals(p.annotations().value(PORT_NAME), "int-to-gateway"))
563 .findAny().orElse(null);
564
565 return port != null ? port.number() : null;
566 }
567
568 public static KubevirtNetwork getExternalNetworkByRouter(KubevirtNetworkService networkService,
569 KubevirtRouter router) {
570 String networkId = router.external().values().stream().findAny().orElse(null);
571 if (networkId == null) {
572 return null;
573 }
574
575 return networkService.network(networkId);
576 }
Jian Li9871cd52021-01-09 00:19:02 +0900577}