blob: cef1f95995d77beaaeac8df8f9ea3206eaa95afe [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 Li16eed162021-01-15 16:58:48 +090019import io.fabric8.kubernetes.client.ConfigBuilder;
20import io.fabric8.kubernetes.client.DefaultKubernetesClient;
21import io.fabric8.kubernetes.client.KubernetesClient;
Jian Li9871cd52021-01-09 00:19:02 +090022import org.apache.commons.lang.StringUtils;
Jian Li7bca1272021-01-14 11:30:36 +090023import org.apache.commons.net.util.SubnetUtils;
24import org.onlab.packet.IpAddress;
Jian Li9871cd52021-01-09 00:19:02 +090025import org.onosproject.cfg.ConfigProperty;
Jian Li16eed162021-01-15 16:58:48 +090026import org.onosproject.kubevirtnode.api.KubevirtApiConfig;
27import org.onosproject.kubevirtnode.api.KubevirtApiConfigService;
Jian Li9871cd52021-01-09 00:19:02 +090028import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
30
Jian Li260231e2021-01-13 18:05:00 +090031import java.io.IOException;
Jian Li7bca1272021-01-14 11:30:36 +090032import java.util.Arrays;
33import java.util.HashSet;
Jian Li260231e2021-01-13 18:05:00 +090034import java.util.List;
Jian Li9871cd52021-01-09 00:19:02 +090035import java.util.Optional;
36import java.util.Set;
Jian Li7bca1272021-01-14 11:30:36 +090037import java.util.stream.Collectors;
Jian Li9871cd52021-01-09 00:19:02 +090038
39/**
40 * An utility that used in KubeVirt networking app.
41 */
42public final class KubevirtNetworkingUtil {
43
44 private static final Logger log = LoggerFactory.getLogger(KubevirtNetworkingUtil.class);
45
46 private static final int PORT_NAME_MAX_LENGTH = 15;
Jian Li16eed162021-01-15 16:58:48 +090047 private static final String COLON_SLASH = "://";
48 private static final String COLON = ":";
Jian Li9871cd52021-01-09 00:19:02 +090049
50 /**
51 * Prevents object installation from external.
52 */
53 private KubevirtNetworkingUtil() {
54 }
55
56 /**
57 * Obtains the boolean property value with specified property key name.
58 *
59 * @param properties a collection of properties
60 * @param name key name
61 * @return mapping value
62 */
63 public static boolean getPropertyValueAsBoolean(Set<ConfigProperty> properties,
64 String name) {
65 Optional<ConfigProperty> property =
66 properties.stream().filter(p -> p.name().equals(name)).findFirst();
67
68 return property.map(ConfigProperty::asBoolean).orElse(false);
69 }
70
71 /**
72 * Re-structures the OVS port name.
73 * The length of OVS port name should be not large than 15.
74 *
75 * @param portName original port name
76 * @return re-structured OVS port name
77 */
78 public static String structurePortName(String portName) {
79
80 // The size of OVS port name should not be larger than 15
81 if (portName.length() > PORT_NAME_MAX_LENGTH) {
82 return StringUtils.substring(portName, 0, PORT_NAME_MAX_LENGTH);
83 }
84
85 return portName;
86 }
Jian Li260231e2021-01-13 18:05:00 +090087
88 /**
89 * Generates string format based on the given string length list.
90 *
91 * @param stringLengths a list of string lengths
92 * @return string format (e.g., %-28s%-15s%-24s%-20s%-15s)
93 */
94 public static String genFormatString(List<Integer> stringLengths) {
95 StringBuilder fsb = new StringBuilder();
96 stringLengths.forEach(length -> {
97 fsb.append("%-");
98 fsb.append(length);
99 fsb.append("s");
100 });
101 return fsb.toString();
102 }
103
104 /**
105 * Prints out the JSON string in pretty format.
106 *
107 * @param mapper Object mapper
108 * @param jsonString JSON string
109 * @return pretty formatted JSON string
110 */
111 public static String prettyJson(ObjectMapper mapper, String jsonString) {
112 try {
113 Object jsonObject = mapper.readValue(jsonString, Object.class);
114 return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject);
115 } catch (IOException e) {
116 log.debug("Json string parsing exception caused by {}", e);
117 }
118 return null;
119 }
Jian Li7bca1272021-01-14 11:30:36 +0900120
121 /**
122 * Obtains valid IP addresses of the given subnet.
123 *
124 * @param cidr CIDR
125 * @return set of IP addresses
126 */
127 public static Set<IpAddress> getSubnetIps(String cidr) {
128 SubnetUtils utils = new SubnetUtils(cidr);
129 utils.setInclusiveHostCount(false);
130 SubnetUtils.SubnetInfo info = utils.getInfo();
131 Set<String> allAddresses =
132 new HashSet<>(Arrays.asList(info.getAllAddresses()));
133
134 if (allAddresses.size() > 2) {
135 allAddresses.remove(info.getLowAddress());
136 allAddresses.remove(info.getHighAddress());
137 }
138
139 return allAddresses.stream()
140 .map(IpAddress::valueOf).collect(Collectors.toSet());
141 }
142
143 /**
144 * Calculate the broadcast address from given IP address and subnet prefix length.
145 *
146 * @param ipAddr IP address
147 * @param prefixLength subnet prefix length
148 * @return broadcast address
149 */
150 public static String getBroadcastAddr(String ipAddr, int prefixLength) {
151 String subnet = ipAddr + "/" + prefixLength;
152 SubnetUtils utils = new SubnetUtils(subnet);
153 return utils.getInfo().getBroadcastAddress();
154 }
Jian Li16eed162021-01-15 16:58:48 +0900155 /**
156 * Generates endpoint URL by referring to scheme, ipAddress and port.
157 *
158 * @param scheme scheme
159 * @param ipAddress IP address
160 * @param port port number
161 * @return generated endpoint URL
162 */
163 public static String endpoint(KubevirtApiConfig.Scheme scheme, IpAddress ipAddress, int port) {
164 StringBuilder endpoint = new StringBuilder();
165 String protocol = org.apache.commons.lang3.StringUtils.lowerCase(scheme.name());
166
167 endpoint.append(protocol);
168 endpoint.append(COLON_SLASH);
169 endpoint.append(ipAddress.toString());
170 endpoint.append(COLON);
171 endpoint.append(port);
172
173 return endpoint.toString();
174 }
175
176 /**
177 * Generates endpoint URL by referring to scheme, ipAddress and port.
178 *
179 * @param apiConfig kubernetes API config
180 * @return generated endpoint URL
181 */
182 public static String endpoint(KubevirtApiConfig apiConfig) {
183 return endpoint(apiConfig.scheme(), apiConfig.ipAddress(), apiConfig.port());
184 }
185
186 /**
187 * Obtains workable kubernetes client.
188 *
189 * @param config kubernetes API config
190 * @return kubernetes client
191 */
192 public static KubernetesClient k8sClient(KubevirtApiConfig config) {
193 if (config == null) {
194 log.warn("Kubernetes API server config is empty.");
195 return null;
196 }
197
198 String endpoint = endpoint(config);
199
200 ConfigBuilder configBuilder = new ConfigBuilder().withMasterUrl(endpoint);
201
202 if (config.scheme() == KubevirtApiConfig.Scheme.HTTPS) {
203 configBuilder.withTrustCerts(true)
204 .withOauthToken(config.token())
205 .withCaCertData(config.caCertData())
206 .withClientCertData(config.clientCertData())
207 .withClientKeyData(config.clientKeyData());
208 }
209
210 return new DefaultKubernetesClient(configBuilder.build());
211 }
212
213 /**
214 * Obtains workable kubernetes client.
215 *
216 * @param service kubernetes API service
217 * @return kubernetes client
218 */
219 public static KubernetesClient k8sClient(KubevirtApiConfigService service) {
220 KubevirtApiConfig config = service.apiConfig();
221 if (config == null) {
222 log.error("Failed to find valid kubernetes API configuration.");
223 return null;
224 }
225
226 KubernetesClient client = k8sClient(config);
227
228 if (client == null) {
229 log.error("Failed to connect to kubernetes API server.");
230 return null;
231 }
232
233 return client;
234 }
Jian Li9871cd52021-01-09 00:19:02 +0900235}