blob: d0fbe643340a0e4f5ed534c5df4ad7249cb83910 [file] [log] [blame]
Jian Li091d8d22018-02-20 10:42:06 +09001/*
2 * Copyright 2018-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.openstacknetworking.util;
17
Daniel Park2ff66b42018-08-01 11:52:45 +090018import com.fasterxml.jackson.core.JsonParseException;
19import com.fasterxml.jackson.core.JsonProcessingException;
20import com.fasterxml.jackson.databind.JsonMappingException;
Jian Li091d8d22018-02-20 10:42:06 +090021import com.fasterxml.jackson.databind.JsonNode;
22import com.fasterxml.jackson.databind.ObjectMapper;
Jian Lieb9f77d2018-02-20 11:25:45 +090023import com.fasterxml.jackson.databind.node.ObjectNode;
Jian Li24ec59f2018-05-23 19:01:25 +090024import com.google.common.base.Strings;
Jian Li7f70bb72018-07-06 23:35:30 +090025import org.onosproject.cfg.ConfigProperty;
Jian Li1064e4f2018-05-29 16:16:53 +090026import org.onosproject.net.DeviceId;
Daniel Park95f73312018-07-31 15:48:34 +090027import org.onosproject.net.device.DeviceService;
Jian Lia171a432018-06-11 11:52:11 +090028import org.onosproject.openstacknetworking.api.InstancePort;
Jian Li24ec59f2018-05-23 19:01:25 +090029import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
Jian Li7f70bb72018-07-06 23:35:30 +090030import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
Jian Liec5c32b2018-07-13 14:28:58 +090031import org.onosproject.openstacknetworking.impl.DefaultInstancePort;
Jian Li51b844c2018-05-31 10:59:03 +090032import org.onosproject.openstacknode.api.OpenstackAuth;
33import org.onosproject.openstacknode.api.OpenstackAuth.Perspective;
Jian Li1064e4f2018-05-29 16:16:53 +090034import org.onosproject.openstacknode.api.OpenstackNode;
Jian Li51b844c2018-05-31 10:59:03 +090035import org.openstack4j.api.OSClient;
36import org.openstack4j.api.client.IOSClientBuilder;
37import org.openstack4j.api.exceptions.AuthenticationException;
38import org.openstack4j.api.types.Facing;
39import org.openstack4j.core.transport.Config;
Jian Li091d8d22018-02-20 10:42:06 +090040import org.openstack4j.core.transport.ObjectMapperSingleton;
41import org.openstack4j.model.ModelEntity;
Jian Li51b844c2018-05-31 10:59:03 +090042import org.openstack4j.model.common.Identifier;
Jian Li24ec59f2018-05-23 19:01:25 +090043import org.openstack4j.model.network.NetFloatingIP;
44import org.openstack4j.model.network.Network;
Jian Lia171a432018-06-11 11:52:11 +090045import org.openstack4j.model.network.Port;
Jian Li0b564282018-06-20 00:50:53 +090046import org.openstack4j.model.network.RouterInterface;
Jian Li51b844c2018-05-31 10:59:03 +090047import org.openstack4j.openstack.OSFactory;
Jian Li0b564282018-06-20 00:50:53 +090048import org.openstack4j.openstack.networking.domain.NeutronRouterInterface;
Jian Li091d8d22018-02-20 10:42:06 +090049import org.slf4j.Logger;
50import org.slf4j.LoggerFactory;
51
Jian Li51b844c2018-05-31 10:59:03 +090052import javax.net.ssl.HostnameVerifier;
53import javax.net.ssl.HttpsURLConnection;
54import javax.net.ssl.SSLContext;
55import javax.net.ssl.TrustManager;
56import javax.net.ssl.X509TrustManager;
Jian Li0b564282018-06-20 00:50:53 +090057import java.io.IOException;
Jian Li091d8d22018-02-20 10:42:06 +090058import java.io.InputStream;
Jian Li51b844c2018-05-31 10:59:03 +090059import java.security.cert.X509Certificate;
Jian Li1064e4f2018-05-29 16:16:53 +090060import java.util.HashMap;
61import java.util.Iterator;
62import java.util.Map;
Daniel Park95f73312018-07-31 15:48:34 +090063import java.util.Objects;
Jian Li7f70bb72018-07-06 23:35:30 +090064import java.util.Optional;
Jian Li1064e4f2018-05-29 16:16:53 +090065import java.util.Set;
66import java.util.TreeMap;
Jian Li091d8d22018-02-20 10:42:06 +090067
68import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
Daniel Park95f73312018-07-31 15:48:34 +090069import static com.google.common.base.Preconditions.checkNotNull;
Jian Li7f024de2018-07-07 03:51:02 +090070import static com.google.common.base.Strings.isNullOrEmpty;
Daniel Park95f73312018-07-31 15:48:34 +090071import static org.onosproject.net.AnnotationKeys.PORT_NAME;
Daniel Parkc4d06402018-05-28 15:57:37 +090072import static org.onosproject.openstacknetworking.api.Constants.PCISLOT;
73import static org.onosproject.openstacknetworking.api.Constants.PCI_VENDOR_INFO;
Ray Milkey9dc57392018-06-08 08:52:31 -070074import static org.onosproject.openstacknetworking.api.Constants.portNamePrefixMap;
Jian Li0b564282018-06-20 00:50:53 +090075import static org.openstack4j.core.transport.ObjectMapperSingleton.getContext;
Jian Li091d8d22018-02-20 10:42:06 +090076
77/**
78 * An utility that used in openstack networking app.
79 */
Jian Lidea0fdb2018-04-02 19:02:48 +090080public final class OpenstackNetworkingUtil {
Jian Li091d8d22018-02-20 10:42:06 +090081
Daniel Park95985382018-07-23 11:38:07 +090082 private static final Logger log = LoggerFactory.getLogger(OpenstackNetworkingUtil.class);
Jian Li091d8d22018-02-20 10:42:06 +090083
Daniel Parkc4d06402018-05-28 15:57:37 +090084 private static final int HEX_RADIX = 16;
Jian Li51b844c2018-05-31 10:59:03 +090085 private static final String ZERO_FUNCTION_NUMBER = "0";
Daniel Parkc4d06402018-05-28 15:57:37 +090086 private static final String PREFIX_DEVICE_NUMBER = "s";
87 private static final String PREFIX_FUNCTION_NUMBER = "f";
88
Jian Li51b844c2018-05-31 10:59:03 +090089 // keystone endpoint related variables
90 private static final String DOMAIN_DEFAULT = "default";
91 private static final String KEYSTONE_V2 = "v2.0";
92 private static final String KEYSTONE_V3 = "v3";
93 private static final String IDENTITY_PATH = "identity/";
94 private static final String SSL_TYPE = "SSL";
95
Jian Li7f024de2018-07-07 03:51:02 +090096 private static final String PROXY_MODE = "proxy";
97 private static final String BROADCAST_MODE = "broadcast";
98
Jian Li24ec59f2018-05-23 19:01:25 +090099 private static final String ERR_FLOW = "Failed set flows for floating IP %s: ";
100
Jian Li091d8d22018-02-20 10:42:06 +0900101 /**
102 * Prevents object instantiation from external.
103 */
Jian Lidea0fdb2018-04-02 19:02:48 +0900104 private OpenstackNetworkingUtil() {
Jian Li091d8d22018-02-20 10:42:06 +0900105 }
106
107 /**
108 * Interprets JSON string to corresponding openstack model entity object.
109 *
110 * @param input JSON string
111 * @param entityClazz openstack model entity class
112 * @return openstack model entity object
113 */
114 public static ModelEntity jsonToModelEntity(InputStream input, Class entityClazz) {
115 ObjectMapper mapper = new ObjectMapper();
116 try {
117 JsonNode jsonTree = mapper.enable(INDENT_OUTPUT).readTree(input);
118 log.trace(new ObjectMapper().writeValueAsString(jsonTree));
119 return ObjectMapperSingleton.getContext(entityClazz)
120 .readerFor(entityClazz)
121 .readValue(jsonTree);
122 } catch (Exception e) {
123 throw new IllegalArgumentException();
124 }
125 }
Jian Lieb9f77d2018-02-20 11:25:45 +0900126
127 /**
128 * Converts openstack model entity object into JSON object.
129 *
130 * @param entity openstack model entity object
131 * @param entityClazz openstack model entity class
132 * @return JSON object
133 */
134 public static ObjectNode modelEntityToJson(ModelEntity entity, Class entityClazz) {
135 ObjectMapper mapper = new ObjectMapper();
136 try {
137 String strModelEntity = ObjectMapperSingleton.getContext(entityClazz)
138 .writerFor(entityClazz)
139 .writeValueAsString(entity);
140 log.trace(strModelEntity);
141 return (ObjectNode) mapper.readTree(strModelEntity.getBytes());
Daniel Park95985382018-07-23 11:38:07 +0900142 } catch (IOException e) {
143 log.error("IOException occurred because of {}", e.toString());
Jian Lieb9f77d2018-02-20 11:25:45 +0900144 throw new IllegalStateException();
145 }
146 }
Jian Li1064e4f2018-05-29 16:16:53 +0900147
148 /**
Jian Li24ec59f2018-05-23 19:01:25 +0900149 * Obtains a floating IP associated with the given instance port.
150 *
151 * @param port instance port
152 * @param fips a collection of floating IPs
153 * @return associated floating IP
154 */
155 public static NetFloatingIP associatedFloatingIp(InstancePort port,
156 Set<NetFloatingIP> fips) {
Daniel Park2ff66b42018-08-01 11:52:45 +0900157 for (NetFloatingIP fip : fips) {
158 if (Strings.isNullOrEmpty(fip.getFixedIpAddress())) {
159 continue;
Jian Li24ec59f2018-05-23 19:01:25 +0900160 }
Daniel Park2ff66b42018-08-01 11:52:45 +0900161 if (Strings.isNullOrEmpty(fip.getFloatingIpAddress())) {
162 continue;
163 }
164 if (fip.getFixedIpAddress().equals(port.ipAddress().toString())) {
165 return fip;
166 }
Jian Li24ec59f2018-05-23 19:01:25 +0900167 }
Daniel Park2ff66b42018-08-01 11:52:45 +0900168
Jian Li24ec59f2018-05-23 19:01:25 +0900169 return null;
170 }
171
172 /**
173 * Checks whether the given floating IP is associated with a VM.
174 *
175 * @param service openstack network service
176 * @param fip floating IP
177 * @return true if the given floating IP associated with a VM, false otherwise
178 */
179 public static boolean isAssociatedWithVM(OpenstackNetworkService service,
180 NetFloatingIP fip) {
181 Port osPort = service.port(fip.getPortId());
182 if (osPort == null) {
183 return false;
184 }
185
186 if (!Strings.isNullOrEmpty(osPort.getDeviceId())) {
187 Network osNet = service.network(osPort.getNetworkId());
188 if (osNet == null) {
189 final String errorFormat = ERR_FLOW + "no network(%s) exists";
190 final String error = String.format(errorFormat,
191 fip.getFloatingIpAddress(), osPort.getNetworkId());
192 throw new IllegalStateException(error);
193 }
194 return true;
195 } else {
196 return false;
197 }
198 }
199
200 /**
Jian Lia171a432018-06-11 11:52:11 +0900201 * Obtains the gateway node by instance port.
202 *
203 * @param gateways a collection of gateway nodes
204 * @param instPort instance port
205 * @return a gateway node
206 */
207 public static OpenstackNode getGwByInstancePort(Set<OpenstackNode> gateways,
208 InstancePort instPort) {
209 OpenstackNode gw = null;
210 if (instPort != null && instPort.deviceId() != null) {
211 gw = getGwByComputeDevId(gateways, instPort.deviceId());
212 }
213 return gw;
214 }
215
216 /**
Jian Li1064e4f2018-05-29 16:16:53 +0900217 * Obtains the gateway node by device in compute node. Note that the gateway
218 * node is determined by device's device identifier.
219 *
220 * @param gws a collection of gateway nodes
221 * @param deviceId device identifier
222 * @return a gateway node
223 */
224 public static OpenstackNode getGwByComputeDevId(Set<OpenstackNode> gws, DeviceId deviceId) {
225 int numOfGw = gws.size();
226
227 if (numOfGw == 0) {
228 return null;
229 }
230
231 int gwIndex = Math.abs(deviceId.hashCode()) % numOfGw;
232
233 return getGwByIndex(gws, gwIndex);
234 }
235
Jian Li51b844c2018-05-31 10:59:03 +0900236 /**
237 * Obtains a connected openstack client.
238 *
239 * @param osNode openstack node
240 * @return a connected openstack client
241 */
242 public static OSClient getConnectedClient(OpenstackNode osNode) {
243 OpenstackAuth auth = osNode.authentication();
244 String endpoint = buildEndpoint(osNode);
245 Perspective perspective = auth.perspective();
Jian Li1064e4f2018-05-29 16:16:53 +0900246
Jian Li51b844c2018-05-31 10:59:03 +0900247 Config config = getSslConfig();
Jian Li1064e4f2018-05-29 16:16:53 +0900248
Jian Li51b844c2018-05-31 10:59:03 +0900249 try {
250 if (endpoint.contains(KEYSTONE_V2)) {
251 IOSClientBuilder.V2 builder = OSFactory.builderV2()
252 .endpoint(endpoint)
253 .tenantName(auth.project())
254 .credentials(auth.username(), auth.password())
255 .withConfig(config);
256
257 if (perspective != null) {
258 builder.perspective(getFacing(perspective));
259 }
260
261 return builder.authenticate();
262 } else if (endpoint.contains(KEYSTONE_V3)) {
263
264 Identifier project = Identifier.byName(auth.project());
265 Identifier domain = Identifier.byName(DOMAIN_DEFAULT);
266
267 IOSClientBuilder.V3 builder = OSFactory.builderV3()
268 .endpoint(endpoint)
269 .credentials(auth.username(), auth.password(), domain)
270 .scopeToProject(project, domain)
271 .withConfig(config);
272
273 if (perspective != null) {
274 builder.perspective(getFacing(perspective));
275 }
276
277 return builder.authenticate();
278 } else {
279 log.warn("Unrecognized keystone version type");
280 return null;
Jian Li1064e4f2018-05-29 16:16:53 +0900281 }
Jian Li51b844c2018-05-31 10:59:03 +0900282 } catch (AuthenticationException e) {
283 log.error("Authentication failed due to {}", e.toString());
284 return null;
Jian Li1064e4f2018-05-29 16:16:53 +0900285 }
Jian Li1064e4f2018-05-29 16:16:53 +0900286 }
Daniel Parkc4d06402018-05-28 15:57:37 +0900287
288 /**
289 * Extract the interface name with the supplied port.
290 *
291 * @param port port
292 * @return interface name
293 */
294 public static String getIntfNameFromPciAddress(Port port) {
Daniel Park95985382018-07-23 11:38:07 +0900295 if (port.getProfile() == null || port.getProfile().isEmpty()) {
Jian Li51b844c2018-05-31 10:59:03 +0900296 log.error("Port profile is not found");
297 return null;
298 }
299
Daniel Park95985382018-07-23 11:38:07 +0900300 if (!port.getProfile().containsKey(PCISLOT) ||
301 Strings.isNullOrEmpty(port.getProfile().get(PCISLOT).toString())) {
Daniel Parkc4d06402018-05-28 15:57:37 +0900302 log.error("Failed to retrieve the interface name because of no pci_slot information from the port");
303 return null;
304 }
Jian Li51b844c2018-05-31 10:59:03 +0900305
Daniel Parkc4d06402018-05-28 15:57:37 +0900306 String busNumHex = port.getProfile().get(PCISLOT).toString().split(":")[1];
307 String busNumDecimal = String.valueOf(Integer.parseInt(busNumHex, HEX_RADIX));
308
309 String deviceNumHex = port.getProfile().get(PCISLOT).toString()
310 .split(":")[2]
311 .split("\\.")[0];
312 String deviceNumDecimal = String.valueOf(Integer.parseInt(deviceNumHex, HEX_RADIX));
313
314 String functionNumHex = port.getProfile().get(PCISLOT).toString()
315 .split(":")[2]
316 .split("\\.")[1];
317 String functionNumDecimal = String.valueOf(Integer.parseInt(functionNumHex, HEX_RADIX));
318
319 String intfName;
320
321 String vendorInfoForPort = String.valueOf(port.getProfile().get(PCI_VENDOR_INFO));
322
Daniel Park95985382018-07-23 11:38:07 +0900323 if (!portNamePrefixMap().containsKey(vendorInfoForPort)) {
324 log.error("Failed to retrieve the interface name because of no port name prefix for vendor ID {}",
325 vendorInfoForPort);
Daniel Parkc4d06402018-05-28 15:57:37 +0900326 return null;
327 }
Ray Milkey9dc57392018-06-08 08:52:31 -0700328 String portNamePrefix = portNamePrefixMap().get(vendorInfoForPort);
Jian Li51b844c2018-05-31 10:59:03 +0900329
Daniel Parkc4d06402018-05-28 15:57:37 +0900330 if (functionNumDecimal.equals(ZERO_FUNCTION_NUMBER)) {
331 intfName = portNamePrefix + busNumDecimal + PREFIX_DEVICE_NUMBER + deviceNumDecimal;
332 } else {
333 intfName = portNamePrefix + busNumDecimal + PREFIX_DEVICE_NUMBER + deviceNumDecimal
334 + PREFIX_FUNCTION_NUMBER + functionNumDecimal;
335 }
336
337 return intfName;
338 }
Jian Li51b844c2018-05-31 10:59:03 +0900339
340 /**
Daniel Park95f73312018-07-31 15:48:34 +0900341 * Check if the given interface is added to the given device or not.
342 *
343 * @param deviceId device ID
344 * @param intfName interface name
345 * @param deviceService device service
346 * @return true if the given interface is added to the given device or false otherwise
347 */
348 public static boolean hasIntfAleadyInDevice(DeviceId deviceId, String intfName, DeviceService deviceService) {
349 checkNotNull(deviceId);
350 checkNotNull(intfName);
351
352 return deviceService.getPorts(deviceId).stream()
353 .anyMatch(port -> Objects.equals(port.annotations().value(PORT_NAME), intfName));
354 }
355
356 /**
Jian Li0b564282018-06-20 00:50:53 +0900357 * Adds router interfaces to openstack admin service.
358 * TODO fix the logic to add router interface to router
359 *
360 * @param osPort port
361 * @param adminService openstack admin service
362 */
363 public static void addRouterIface(Port osPort, OpenstackRouterAdminService adminService) {
364 osPort.getFixedIps().forEach(p -> {
365 JsonNode jsonTree = new ObjectMapper().createObjectNode()
366 .put("id", osPort.getDeviceId())
367 .put("tenant_id", osPort.getTenantId())
368 .put("subnet_id", p.getSubnetId())
369 .put("port_id", osPort.getId());
370 try {
371 RouterInterface rIface = getContext(NeutronRouterInterface.class)
372 .readerFor(NeutronRouterInterface.class)
373 .readValue(jsonTree);
374 if (adminService.routerInterface(rIface.getPortId()) != null) {
375 adminService.updateRouterInterface(rIface);
376 } else {
377 adminService.addRouterInterface(rIface);
378 }
379 } catch (IOException ignore) {
Daniel Park2ff66b42018-08-01 11:52:45 +0900380 log.error("Exception occurred because of {}", ignore.toString());
Jian Li0b564282018-06-20 00:50:53 +0900381 }
382 });
383 }
384
385 /**
Jian Li7f70bb72018-07-06 23:35:30 +0900386 * Obtains the property value with specified property key name.
387 *
388 * @param properties a collection of properties
389 * @param name key name
390 * @return mapping value
391 */
392 public static String getPropertyValue(Set<ConfigProperty> properties, String name) {
393 Optional<ConfigProperty> property =
394 properties.stream().filter(p -> p.name().equals(name)).findFirst();
395 return property.map(ConfigProperty::value).orElse(null);
396 }
397
398 /**
Jian Lif1efbe52018-07-17 23:20:16 +0900399 * Prints out the JSON string in pretty format.
400 *
401 * @param mapper Object mapper
402 * @param jsonString JSON string
403 * @return pretty formatted JSON string
404 */
405 public static String prettyJson(ObjectMapper mapper, String jsonString) {
406 try {
407 Object jsonObject = mapper.readValue(jsonString, Object.class);
408 return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject);
Daniel Park2ff66b42018-08-01 11:52:45 +0900409 } catch (JsonParseException e) {
410 log.debug("JsonParseException caused by {}", e);
411 } catch (JsonMappingException e) {
412 log.debug("JsonMappingException caused by {}", e);
413 } catch (JsonProcessingException e) {
414 log.debug("JsonProcessingException caused by {}", e);
Jian Lif1efbe52018-07-17 23:20:16 +0900415 } catch (IOException e) {
Daniel Park2ff66b42018-08-01 11:52:45 +0900416 log.debug("IOException caused by {}", e);
Jian Lif1efbe52018-07-17 23:20:16 +0900417 }
418 return null;
419 }
420
421 /**
Jian Li7f024de2018-07-07 03:51:02 +0900422 * Checks the validity of ARP mode.
423 *
424 * @param arpMode ARP mode
425 * @return returns true if the ARP mode is valid, false otherwise
426 */
427 public static boolean checkArpMode(String arpMode) {
428
429 if (isNullOrEmpty(arpMode)) {
430 return false;
431 } else {
432 return arpMode.equals(PROXY_MODE) || arpMode.equals(BROADCAST_MODE);
433 }
434 }
435
436 /**
Jian Liec5c32b2018-07-13 14:28:58 +0900437 * Swaps current location with old location info.
438 * The revised instance port will be used to mod the flow rules after migration.
439 *
440 * @param instPort instance port
441 * @return location swapped instance port
442 */
443 public static InstancePort swapStaleLocation(InstancePort instPort) {
444 return DefaultInstancePort.builder()
445 .deviceId(instPort.oldDeviceId())
446 .portNumber(instPort.oldPortNumber())
447 .state(instPort.state())
448 .ipAddress(instPort.ipAddress())
449 .macAddress(instPort.macAddress())
450 .networkId(instPort.networkId())
451 .portId(instPort.portId())
452 .build();
453 }
454
455 /**
Daniel Park2ff66b42018-08-01 11:52:45 +0900456 * Compares two router interfaces are equal.
457 * Will be remove this after Openstack4j implements equals.
458 *
459 * @param routerInterface1 router interface
460 * @param routerInterface2 router interface
461 * @return returns true if two router interfaces are equal, false otherwise
462 */
463 public static boolean routerInterfacesEquals(RouterInterface routerInterface1, RouterInterface routerInterface2) {
464 return Objects.equals(routerInterface1.getId(), routerInterface2.getId()) &&
465 Objects.equals(routerInterface1.getPortId(), routerInterface2.getPortId()) &&
466 Objects.equals(routerInterface1.getSubnetId(), routerInterface2.getSubnetId()) &&
467 Objects.equals(routerInterface1.getTenantId(), routerInterface2.getTenantId());
468 }
469
470 /**
Jian Li51b844c2018-05-31 10:59:03 +0900471 * Builds up and a complete endpoint URL from gateway node.
472 *
473 * @param node gateway node
474 * @return a complete endpoint URL
475 */
476 private static String buildEndpoint(OpenstackNode node) {
477
478 OpenstackAuth auth = node.authentication();
479
480 StringBuilder endpointSb = new StringBuilder();
481 endpointSb.append(auth.protocol().name().toLowerCase());
482 endpointSb.append("://");
483 endpointSb.append(node.endPoint());
484 endpointSb.append(":");
485 endpointSb.append(auth.port());
486 endpointSb.append("/");
487
488 // in case the version is v3, we need to append identity path into endpoint
489 if (auth.version().equals(KEYSTONE_V3)) {
490 endpointSb.append(IDENTITY_PATH);
491 }
492
493 endpointSb.append(auth.version());
494 return endpointSb.toString();
495 }
496
497 /**
498 * Obtains the SSL config without verifying the certification.
499 *
500 * @return SSL config
501 */
502 private static Config getSslConfig() {
503 // we bypass the SSL certification verification for now
504 // TODO: verify server side SSL using a given certification
505 Config config = Config.newConfig().withSSLVerificationDisabled();
506
507 TrustManager[] trustAllCerts = new TrustManager[]{
508 new X509TrustManager() {
509 public X509Certificate[] getAcceptedIssuers() {
510 return null;
511 }
512
513 public void checkClientTrusted(X509Certificate[] certs,
514 String authType) {
515 }
516
517 public void checkServerTrusted(X509Certificate[] certs,
518 String authType) {
519 }
520 }
521 };
522
523 HostnameVerifier allHostsValid = (hostname, session) -> true;
524
525 try {
526 SSLContext sc = SSLContext.getInstance(SSL_TYPE);
527 sc.init(null, trustAllCerts,
528 new java.security.SecureRandom());
529 HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
530 HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
531
532 config.withSSLContext(sc);
533 } catch (Exception e) {
534 log.error("Failed to access OpenStack service due to {}", e.toString());
535 return null;
536 }
537
538 return config;
539 }
540
541 /**
542 * Obtains the facing object with given openstack perspective.
543 *
544 * @param perspective keystone perspective
545 * @return facing object
546 */
547 private static Facing getFacing(Perspective perspective) {
548
549 switch (perspective) {
550 case PUBLIC:
551 return Facing.PUBLIC;
552 case ADMIN:
553 return Facing.ADMIN;
554 case INTERNAL:
555 return Facing.INTERNAL;
556 default:
557 return null;
558 }
559 }
560
561 /**
562 * Obtains gateway instance by giving index number.
563 *
564 * @param gws a collection of gateway nodes
565 * @param index index number
566 * @return gateway instance
567 */
568 private static OpenstackNode getGwByIndex(Set<OpenstackNode> gws, int index) {
569 Map<String, OpenstackNode> hashMap = new HashMap<>();
570 gws.forEach(gw -> hashMap.put(gw.hostname(), gw));
571 TreeMap<String, OpenstackNode> treeMap = new TreeMap<>(hashMap);
572 Iterator<String> iteratorKey = treeMap.keySet().iterator();
573
574 int intIndex = 0;
575 OpenstackNode gw = null;
576 while (iteratorKey.hasNext()) {
577 String key = iteratorKey.next();
578
579 if (intIndex == index) {
580 gw = treeMap.get(key);
581 }
582 intIndex++;
583 }
584 return gw;
585 }
Jian Li091d8d22018-02-20 10:42:06 +0900586}