blob: 2413f46d0ec9d45f9fd7e0f26dd352883d6fdaa9 [file] [log] [blame]
Jian Lif16e8852019-01-22 22:55:31 +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.util;
17
18import com.fasterxml.jackson.databind.ObjectMapper;
19import com.google.common.base.Strings;
Jian Li1cee9882019-02-13 11:25:25 +090020import io.fabric8.kubernetes.client.ConfigBuilder;
21import io.fabric8.kubernetes.client.DefaultKubernetesClient;
22import io.fabric8.kubernetes.client.KubernetesClient;
Jian Li3defa842019-02-12 00:31:35 +090023import org.apache.commons.lang.StringUtils;
24import org.onlab.packet.IpAddress;
25import org.onosproject.k8snode.api.K8sApiConfig;
26import org.onosproject.k8snode.api.K8sApiConfig.Scheme;
Jian Lif16e8852019-01-22 22:55:31 +090027import org.onosproject.k8snode.api.K8sNode;
28import org.onosproject.net.Device;
29import org.onosproject.net.behaviour.BridgeConfig;
30import org.onosproject.net.behaviour.BridgeName;
31import org.onosproject.net.device.DeviceService;
32import org.onosproject.ovsdb.controller.OvsdbClientService;
33import org.onosproject.ovsdb.controller.OvsdbController;
34import org.onosproject.ovsdb.controller.OvsdbNodeId;
35import org.slf4j.Logger;
36import org.slf4j.LoggerFactory;
37
38import java.io.IOException;
39import java.util.Dictionary;
40
41import static org.onlab.util.Tools.get;
42
43/**
44 * An utility that used in kubernetes node app.
45 */
46public final class K8sNodeUtil {
47 private static final Logger log = LoggerFactory.getLogger(K8sNodeUtil.class);
48
Jian Li3defa842019-02-12 00:31:35 +090049 private static final String COLON_SLASH = "://";
50 private static final String COLON = ":";
51
Jian Li1cee9882019-02-13 11:25:25 +090052 private static final int HEX_LENGTH = 16;
53 private static final String OF_PREFIX = "of:";
54 private static final String ZERO = "0";
55
Jian Lif16e8852019-01-22 22:55:31 +090056 /**
57 * Prevents object installation from external.
58 */
59 private K8sNodeUtil() {
60 }
61
62 /**
63 * Checks whether the controller has a connection with an OVSDB that resides
64 * inside the given kubernetes node.
65 *
66 * @param node kubernetes node
67 * @param ovsdbPort OVSDB port
68 * @param ovsdbController OVSDB controller
69 * @param deviceService device service
70 * @return true if the controller is connected to the OVSDB, false otherwise
71 */
72 public static boolean isOvsdbConnected(K8sNode node,
73 int ovsdbPort,
74 OvsdbController ovsdbController,
75 DeviceService deviceService) {
76 OvsdbClientService client = getOvsdbClient(node, ovsdbPort, ovsdbController);
77 return deviceService.isAvailable(node.ovsdb()) &&
78 client != null &&
79 client.isConnected();
80 }
81
82 /**
83 * Gets the ovsdb client with supplied openstack node.
84 *
85 * @param node kubernetes node
86 * @param ovsdbPort ovsdb port
87 * @param ovsdbController ovsdb controller
88 * @return ovsdb client
89 */
90 public static OvsdbClientService getOvsdbClient(K8sNode node,
91 int ovsdbPort,
92 OvsdbController ovsdbController) {
93 OvsdbNodeId ovsdb = new OvsdbNodeId(node.managementIp(), ovsdbPort);
94 return ovsdbController.getOvsdbClient(ovsdb);
95 }
96
97 /**
98 * Adds or removes a network interface (aka port) into a given bridge of kubernetes node.
99 *
100 * @param k8sNode kubernetes node
101 * @param bridgeName bridge name
102 * @param intfName interface name
103 * @param deviceService device service
104 * @param addOrRemove add port is true, remove it otherwise
105 */
106 public static synchronized void addOrRemoveSystemInterface(K8sNode k8sNode,
107 String bridgeName,
108 String intfName,
109 DeviceService deviceService,
110 boolean addOrRemove) {
111
112
113 Device device = deviceService.getDevice(k8sNode.ovsdb());
114 if (device == null || !device.is(BridgeConfig.class)) {
115 log.info("device is null or this device if not ovsdb device");
116 return;
117 }
118 BridgeConfig bridgeConfig = device.as(BridgeConfig.class);
119
120 if (addOrRemove) {
121 bridgeConfig.addPort(BridgeName.bridgeName(bridgeName), intfName);
122 } else {
123 bridgeConfig.deletePort(BridgeName.bridgeName(bridgeName), intfName);
124 }
125 }
126
127 /**
128 * Gets Boolean property from the propertyName
129 * Return null if propertyName is not found.
130 *
131 * @param properties properties to be looked up
132 * @param propertyName the name of the property to look up
133 * @return value when the propertyName is defined or return null
134 */
135 public static Boolean getBooleanProperty(Dictionary<?, ?> properties,
136 String propertyName) {
137 Boolean value;
138 try {
139 String s = get(properties, propertyName);
140 value = Strings.isNullOrEmpty(s) ? null : Boolean.valueOf(s);
141 } catch (ClassCastException e) {
142 value = null;
143 }
144 return value;
145 }
146
147 /**
148 * Prints out the JSON string in pretty format.
149 *
150 * @param mapper Object mapper
151 * @param jsonString JSON string
152 * @return pretty formatted JSON string
153 */
154 public static String prettyJson(ObjectMapper mapper, String jsonString) {
155 try {
156 Object jsonObject = mapper.readValue(jsonString, Object.class);
157 return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject);
158 } catch (IOException e) {
159 log.debug("Json string parsing exception caused by {}", e);
160 }
161 return null;
162 }
Jian Li3defa842019-02-12 00:31:35 +0900163
164 /**
165 * Generates endpoint URL by referring to scheme, ipAddress and port.
166 *
167 * @param scheme scheme
168 * @param ipAddress IP address
169 * @param port port number
170 * @return generated endpoint URL
171 */
172 public static String endpoint(Scheme scheme, IpAddress ipAddress, int port) {
173 StringBuilder endpoint = new StringBuilder();
174 String protocol = StringUtils.lowerCase(scheme.name());
175
176 endpoint.append(protocol);
177 endpoint.append(COLON_SLASH);
178 endpoint.append(ipAddress.toString());
179 endpoint.append(COLON);
180 endpoint.append(port);
181
182 return endpoint.toString();
183 }
184
185 /**
186 * Generates endpoint URL by referring to scheme, ipAddress and port.
187 *
188 * @param apiConfig kubernetes API config
189 * @return generated endpoint URL
190 */
191 public static String endpoint(K8sApiConfig apiConfig) {
192 return endpoint(apiConfig.scheme(), apiConfig.ipAddress(), apiConfig.port());
193 }
Jian Li1cee9882019-02-13 11:25:25 +0900194
195 /**
196 * Generates a DPID (of:0000000000000001) from an index value.
197 *
198 * @param index index value
199 * @return generated DPID
200 */
201 public static String genDpid(long index) {
202 if (index < 0) {
203 return null;
204 }
205
206 String hexStr = Long.toHexString(index);
207
208 StringBuilder zeroPadding = new StringBuilder();
209 for (int i = 0; i < HEX_LENGTH - hexStr.length(); i++) {
210 zeroPadding.append(ZERO);
211 }
212
213 return OF_PREFIX + zeroPadding.toString() + hexStr;
214 }
215
216 /**
217 * Obtains workable kubernetes client.
218 *
219 * @param config kubernetes API config
220 * @return kubernetes client
221 */
222 public static KubernetesClient k8sClient(K8sApiConfig config) {
223 if (config == null) {
224 log.warn("Kubernetes API server config is empty.");
225 return null;
226 }
227
228 String endpoint = endpoint(config);
229
230 ConfigBuilder configBuilder = new ConfigBuilder().withMasterUrl(endpoint);
231
232 if (config.scheme() == K8sApiConfig.Scheme.HTTPS) {
233 configBuilder.withTrustCerts(true)
234 .withOauthToken(config.token())
235 .withCaCertData(config.caCertData())
236 .withClientCertData(config.clientCertData())
237 .withClientKeyData(config.clientKeyData());
238 }
239
240 return new DefaultKubernetesClient(configBuilder.build());
241 }
Jian Lif16e8852019-01-22 22:55:31 +0900242}