blob: a6ac2299ba2919603ee027240daf4c627105b352 [file] [log] [blame]
Jian Li43244382021-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 Lif97a07e2021-01-13 18:05:00 +090018import com.fasterxml.jackson.databind.ObjectMapper;
Jian Li556709c2021-02-03 17:54:28 +090019import com.google.common.base.Strings;
Jian Lid4296d02021-03-12 18:03:58 +090020import com.google.common.collect.ImmutableSet;
Jian Lica20b712021-01-18 00:19:31 +090021import io.fabric8.kubernetes.api.model.Pod;
Jian Li034820d2021-01-15 16:58:48 +090022import io.fabric8.kubernetes.client.ConfigBuilder;
23import io.fabric8.kubernetes.client.DefaultKubernetesClient;
24import io.fabric8.kubernetes.client.KubernetesClient;
Jian Li43244382021-01-09 00:19:02 +090025import org.apache.commons.lang.StringUtils;
Jian Li3ba5c582021-01-14 11:30:36 +090026import org.apache.commons.net.util.SubnetUtils;
Jian Lica20b712021-01-18 00:19:31 +090027import org.json.JSONArray;
28import org.json.JSONException;
29import org.json.JSONObject;
Jian Li858ccd72021-02-04 17:25:01 +090030import org.onlab.osgi.DefaultServiceDirectory;
Daniel Park2884b232021-03-04 18:58:47 +090031import org.onlab.packet.Ip4Address;
Jian Li3ba5c582021-01-14 11:30:36 +090032import org.onlab.packet.IpAddress;
Jian Lica20b712021-01-18 00:19:31 +090033import org.onlab.packet.MacAddress;
Jian Li43244382021-01-09 00:19:02 +090034import org.onosproject.cfg.ConfigProperty;
Jian Lica20b712021-01-18 00:19:31 +090035import org.onosproject.kubevirtnetworking.api.DefaultKubevirtPort;
36import org.onosproject.kubevirtnetworking.api.KubevirtNetwork;
Daniel Parkf3136042021-03-10 07:49:11 +090037import org.onosproject.kubevirtnetworking.api.KubevirtNetworkService;
Jian Lica20b712021-01-18 00:19:31 +090038import org.onosproject.kubevirtnetworking.api.KubevirtPort;
Daniel Park2884b232021-03-04 18:58:47 +090039import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
40import org.onosproject.kubevirtnetworking.api.KubevirtRouterService;
Jian Li034820d2021-01-15 16:58:48 +090041import org.onosproject.kubevirtnode.api.KubevirtApiConfig;
42import org.onosproject.kubevirtnode.api.KubevirtApiConfigService;
Jian Li858ccd72021-02-04 17:25:01 +090043import org.onosproject.kubevirtnode.api.KubevirtNode;
Daniel Park2884b232021-03-04 18:58:47 +090044import org.onosproject.kubevirtnode.api.KubevirtNodeService;
Jian Li858ccd72021-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 Li43244382021-01-09 00:19:02 +090049import org.slf4j.Logger;
50import org.slf4j.LoggerFactory;
51
Jian Lif97a07e2021-01-13 18:05:00 +090052import java.io.IOException;
Jian Li3ba5c582021-01-14 11:30:36 +090053import java.util.Arrays;
54import java.util.HashSet;
Jian Lif97a07e2021-01-13 18:05:00 +090055import java.util.List;
Jian Lica20b712021-01-18 00:19:31 +090056import java.util.Map;
Jian Li858ccd72021-02-04 17:25:01 +090057import java.util.Objects;
Jian Li43244382021-01-09 00:19:02 +090058import java.util.Optional;
59import java.util.Set;
Jian Li3ba5c582021-01-14 11:30:36 +090060import java.util.stream.Collectors;
Jian Li43244382021-01-09 00:19:02 +090061
Jian Li858ccd72021-02-04 17:25:01 +090062import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_TO_TENANT_PREFIX;
Daniel Park2884b232021-03-04 18:58:47 +090063import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.GATEWAY;
Jian Li858ccd72021-02-04 17:25:01 +090064import static org.onosproject.net.AnnotationKeys.PORT_NAME;
65
Jian Li43244382021-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 Li034820d2021-01-15 16:58:48 +090074 private static final String COLON_SLASH = "://";
75 private static final String COLON = ":";
Jian Li556709c2021-02-03 17:54:28 +090076 private static final String OF_PREFIX = "of:";
Jian Li43244382021-01-09 00:19:02 +090077
Jian Lica20b712021-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 Parkbabde9c2021-03-09 13:37:42 +090083 private static final String BR_INT = "br-int";
Jian Lica20b712021-01-18 00:19:31 +090084
Jian Li43244382021-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 Park2884b232021-03-04 18:58:47 +090094 * @param properties a collection of properties
95 * @param name key name
Jian Li43244382021-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 Park2884b232021-03-04 18:58:47 +0900110 * @param portName original port name
Jian Li43244382021-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 Lif97a07e2021-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 Li556709c2021-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 Lif97a07e2021-01-13 18:05:00 +0900155 * Prints out the JSON string in pretty format.
156 *
Daniel Park2884b232021-03-04 18:58:47 +0900157 * @param mapper Object mapper
158 * @param jsonString JSON string
Jian Lif97a07e2021-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 Li3ba5c582021-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 Park2884b232021-03-04 18:58:47 +0900196 * @param ipAddr IP address
197 * @param prefixLength subnet prefix length
Jian Li3ba5c582021-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 Park2884b232021-03-04 18:58:47 +0900205
Jian Li034820d2021-01-15 16:58:48 +0900206 /**
207 * Generates endpoint URL by referring to scheme, ipAddress and port.
208 *
Daniel Park2884b232021-03-04 18:58:47 +0900209 * @param scheme scheme
210 * @param ipAddress IP address
211 * @param port port number
Jian Li034820d2021-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 Park2884b232021-03-04 18:58:47 +0900230 * @param apiConfig kubernetes API config
Jian Li034820d2021-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 Li034820d2021-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 Lica20b712021-01-18 00:19:31 +0900285
286 /**
Jian Li556709c2021-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 Li858ccd72021-02-04 17:25:01 +0900298 * Obtains the tunnel port number with the given network and node.
299 *
300 * @param network kubevirt network
Daniel Park2884b232021-03-04 18:58:47 +0900301 * @param node kubevirt node
Jian Li858ccd72021-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 Lica20b712021-01-18 00:19:31 +0900319 * Obtains the kubevirt port from kubevirt POD.
320 *
Daniel Parkf3136042021-03-10 07:49:11 +0900321 * @param nodeService kubevirt node service
Jian Lica20b712021-01-18 00:19:31 +0900322 * @param networks set of existing kubevirt networks
Daniel Park2884b232021-03-04 18:58:47 +0900323 * @param pod kubevirt POD
Jian Lid4296d02021-03-12 18:03:58 +0900324 * @return kubevirt ports attached to the POD
Jian Lica20b712021-01-18 00:19:31 +0900325 */
Jian Lib6dc08f2021-03-24 15:24:18 +0900326 public static Set<KubevirtPort> getPorts(KubevirtNodeService nodeService,
327 Set<KubevirtNetwork> networks, Pod pod) {
Jian Lica20b712021-01-18 00:19:31 +0900328 try {
329 Map<String, String> annots = pod.getMetadata().getAnnotations();
Jian Li6e66a302021-01-21 20:30:52 +0900330 if (annots == null) {
Jian Lid4296d02021-03-12 18:03:58 +0900331 return ImmutableSet.of();
Jian Li6e66a302021-01-21 20:30:52 +0900332 }
333
Jian Li7a581b12021-02-18 14:24:32 +0900334 if (!annots.containsKey(NETWORK_STATUS_KEY)) {
Jian Lid4296d02021-03-12 18:03:58 +0900335 return ImmutableSet.of();
Jian Li7a581b12021-02-18 14:24:32 +0900336 }
337
Jian Lica20b712021-01-18 00:19:31 +0900338 String networkStatusStr = annots.get(NETWORK_STATUS_KEY);
339
340 if (networkStatusStr == null) {
Jian Lid4296d02021-03-12 18:03:58 +0900341 return ImmutableSet.of();
Jian Lica20b712021-01-18 00:19:31 +0900342 }
Jian Lib6dc08f2021-03-24 15:24:18 +0900343
Daniel Parkf3136042021-03-10 07:49:11 +0900344 KubevirtPort.Builder builder = DefaultKubevirtPort.builder();
345
346 KubevirtNode node = nodeService.node(pod.getSpec().getNodeName());
Jian Lib6dc08f2021-03-24 15:24:18 +0900347
Daniel Parkf3136042021-03-10 07:49:11 +0900348 if (node != null) {
349 builder.deviceId(node.intgBridge());
350 }
Jian Lica20b712021-01-18 00:19:31 +0900351
352 JSONArray networkStatus = new JSONArray(networkStatusStr);
Jian Lid4296d02021-03-12 18:03:58 +0900353 Set<KubevirtPort> ports = new HashSet<>();
Jian Lica20b712021-01-18 00:19:31 +0900354
355 for (int i = 0; i < networkStatus.length(); i++) {
356 JSONObject object = networkStatus.getJSONObject(i);
357 String name = object.getString(NAME);
358 KubevirtNetwork network = networks.stream()
359 .filter(n -> (NETWORK_PREFIX + n.name()).equals(name))
360 .findAny().orElse(null);
361 if (network != null) {
362 String mac = object.getString(MAC);
363
Daniel Parkf3136042021-03-10 07:49:11 +0900364 builder.macAddress(MacAddress.valueOf(mac))
Jian Lica20b712021-01-18 00:19:31 +0900365 .networkId(network.networkId());
366
Jian Lid4296d02021-03-12 18:03:58 +0900367 ports.add(builder.build());
Jian Lica20b712021-01-18 00:19:31 +0900368 }
369 }
370
Jian Lid4296d02021-03-12 18:03:58 +0900371 return ports;
372
Jian Lica20b712021-01-18 00:19:31 +0900373 } catch (JSONException e) {
374 log.error("Failed to parse network status object", e);
375 }
376
Jian Lid4296d02021-03-12 18:03:58 +0900377 return ImmutableSet.of();
Jian Lica20b712021-01-18 00:19:31 +0900378 }
Jian Li858ccd72021-02-04 17:25:01 +0900379
380 /**
381 * Obtains the tunnel bridge to tenant bridge patch port number.
382 *
Daniel Park2884b232021-03-04 18:58:47 +0900383 * @param node kubevirt node
Jian Li858ccd72021-02-04 17:25:01 +0900384 * @param network kubevirt network
385 * @return patch port number
386 */
387 public static PortNumber tunnelToTenantPort(KubevirtNode node, KubevirtNetwork network) {
388 if (network.segmentId() == null) {
389 return null;
390 }
391
392 if (node.tunBridge() == null) {
393 return null;
394 }
395
396 String tunToTenantPortName = TUNNEL_TO_TENANT_PREFIX + segmentIdHex(network.segmentId());
397 return portNumber(node.tunBridge(), tunToTenantPortName);
398 }
399
400 /**
401 * Obtains the tunnel port number of the given node.
402 *
Daniel Park2884b232021-03-04 18:58:47 +0900403 * @param node kubevirt node
Jian Li858ccd72021-02-04 17:25:01 +0900404 * @param network kubevirt network
405 * @return tunnel port number
406 */
407 public static PortNumber tunnelPort(KubevirtNode node, KubevirtNetwork network) {
408 if (network.segmentId() == null) {
409 return null;
410 }
411
412 if (node.tunBridge() == null) {
413 return null;
414 }
415
416 switch (network.type()) {
417 case VXLAN:
418 return node.vxlanPort();
419 case GRE:
420 return node.grePort();
421 case GENEVE:
422 return node.genevePort();
423 case FLAT:
Jian Li2ce718e2021-02-17 20:42:15 +0900424 case VLAN:
Jian Li858ccd72021-02-04 17:25:01 +0900425 default:
426 // do nothing
427 return null;
428 }
429 }
430
Jian Li810f58c2021-02-27 01:10:50 +0900431 public static String parseResourceName(String resource) {
432 try {
433 JSONObject json = new JSONObject(resource);
434 return json.getJSONObject("metadata").getString("name");
435 } catch (JSONException e) {
436 log.error("");
437 }
438 return "";
439 }
440
Daniel Parkf3136042021-03-10 07:49:11 +0900441 public static PortNumber portNumber(DeviceId deviceId, String portName) {
Jian Li858ccd72021-02-04 17:25:01 +0900442 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
443 Port port = deviceService.getPorts(deviceId).stream()
444 .filter(p -> p.isEnabled() &&
445 Objects.equals(p.annotations().value(PORT_NAME), portName))
446 .findAny().orElse(null);
447 return port != null ? port.number() : null;
448 }
449
Daniel Park2884b232021-03-04 18:58:47 +0900450 /**
451 * Returns the gateway node for the specified kubevirt router.
452 * Among gateways, only one gateway would act as a gateway per perter.
453 * Currently gateway node is selected based on modulo operation with router hashcode.
454 *
455 * @param nodeService kubevirt node service
456 * @param router kubevirt router
457 * @return elected gateway node
458 */
459 public static KubevirtNode gatewayNodeForSpecifiedRouter(KubevirtNodeService nodeService,
460 KubevirtRouter router) {
461 //TODO: enhance election logic for a better load balancing
462
463 int numOfGateways = nodeService.completeNodes(GATEWAY).size();
464 if (numOfGateways == 0) {
465 return null;
466 }
467 return (KubevirtNode) nodeService.completeNodes(GATEWAY).toArray()[router.hashCode() % numOfGateways];
468 }
469
470 /**
Daniel Parkf3136042021-03-10 07:49:11 +0900471 * Returns the mac address of the router.
472 *
473 * @param router kubevirt router
474 * @return macc address of the router
475 */
476 public static MacAddress getRouterMacAddress(KubevirtRouter router) {
477 if (router.mac() == null) {
478 log.warn("Failed to get mac address of router {}", router.name());
479 }
480
481 return router.mac();
Daniel Park2884b232021-03-04 18:58:47 +0900482 }
483
484 /**
485 * Returns the snat ip address with specified router.
486 *
487 * @param routerService router service
488 * @param internalNetworkId internal network id which is associated with the router
489 * @return snat ip address if exist, null otherwise
490 */
491 public static IpAddress getRouterSnatIpAddress(KubevirtRouterService routerService,
492 String internalNetworkId) {
493 KubevirtRouter router = routerService.routers().stream()
494 .filter(r -> r.internal().contains(internalNetworkId))
495 .findAny().orElse(null);
496
497 if (router == null) {
498 return null;
499 }
500
501 String routerSnatIp = router.external().keySet().stream().findAny().orElse(null);
502
503 if (routerSnatIp == null) {
504 return null;
505 }
506
507 return Ip4Address.valueOf(routerSnatIp);
508 }
Daniel Parkbabde9c2021-03-09 13:37:42 +0900509
510 /**
511 * Returns the kubevirt router with specified kubevirt port.
512 *
513 * @param routerService kubevirt router service
514 * @param kubevirtPort kubevirt port
515 * @return kubevirt router
516 */
517 public static KubevirtRouter getRouterForKubevirtPort(KubevirtRouterService routerService,
518 KubevirtPort kubevirtPort) {
519 if (kubevirtPort.ipAddress() != null) {
520 return routerService.routers().stream()
521 .filter(r -> r.internal().contains(kubevirtPort.networkId()))
522 .findAny().orElse(null);
523 }
524 return null;
525 }
526
527 /**
528 * Returns the kubevirt router with specified kubevirt network.
529 *
530 * @param routerService kubevirt router service
531 * @param kubevirtNetwork kubevirt network
532 * @return kubevirt router
533 */
534 public static KubevirtRouter getRouterForKubevirtNetwork(KubevirtRouterService routerService,
535 KubevirtNetwork kubevirtNetwork) {
536 return routerService.routers().stream()
537 .filter(router -> router.internal().contains(kubevirtNetwork.networkId()))
538 .findAny().orElse(null);
539 }
Daniel Parkf3136042021-03-10 07:49:11 +0900540
541 /**
542 * Returns the external patch port number with specified gateway.
543 *
544 * @param deviceService device service
Jian Li9793ec42021-03-19 15:03:32 +0900545 * @param gatewayNode gateway node
Daniel Parkf3136042021-03-10 07:49:11 +0900546 * @return external patch port number
547 */
548 public static PortNumber externalPatchPortNum(DeviceService deviceService, KubevirtNode gatewayNode) {
Jian Li63f191f2021-03-25 17:14:40 +0900549 String gatewayBridgeName = gatewayNode.gatewayBridgeName();
550 if (gatewayBridgeName == null) {
Jian Li9793ec42021-03-19 15:03:32 +0900551 log.warn("No external interface is attached to gateway {}", gatewayNode.hostname());
552 return null;
553 }
554
Jian Li63f191f2021-03-25 17:14:40 +0900555 String patchPortName = "int-to-" + gatewayBridgeName;
Daniel Parkf3136042021-03-10 07:49:11 +0900556 Port port = deviceService.getPorts(gatewayNode.intgBridge()).stream()
557 .filter(p -> p.isEnabled() &&
Jian Li9793ec42021-03-19 15:03:32 +0900558 Objects.equals(p.annotations().value(PORT_NAME), patchPortName))
Daniel Parkf3136042021-03-10 07:49:11 +0900559 .findAny().orElse(null);
560
561 return port != null ? port.number() : null;
562 }
563
564 public static KubevirtNetwork getExternalNetworkByRouter(KubevirtNetworkService networkService,
565 KubevirtRouter router) {
566 String networkId = router.external().values().stream().findAny().orElse(null);
567 if (networkId == null) {
568 return null;
569 }
570
571 return networkService.network(networkId);
572 }
Jian Li43244382021-01-09 00:19:02 +0900573}