blob: 1d3512ab2b0c81111227344baf63055e93e57ee5 [file] [log] [blame]
Jian Li43dc9ca2020-12-19 04:01:49 +09001/*
2 * Copyright 2020-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.kubevirtnode.api;
17
18import com.google.common.base.MoreObjects;
19import org.apache.commons.lang.StringUtils;
Jian Li543fe852021-02-04 17:25:01 +090020import org.onlab.osgi.DefaultServiceDirectory;
Jian Li43dc9ca2020-12-19 04:01:49 +090021import org.onlab.packet.IpAddress;
22import org.onosproject.net.DeviceId;
Jian Li543fe852021-02-04 17:25:01 +090023import org.onosproject.net.Port;
24import org.onosproject.net.PortNumber;
25import org.onosproject.net.device.DeviceService;
Jian Li43dc9ca2020-12-19 04:01:49 +090026
27import java.util.ArrayList;
28import java.util.Collection;
29import java.util.Objects;
30
31import static com.google.common.base.Preconditions.checkArgument;
32import static org.onosproject.kubevirtnode.api.Constants.DEFAULT_CLUSTER_NAME;
Jian Li543fe852021-02-04 17:25:01 +090033import static org.onosproject.kubevirtnode.api.Constants.GENEVE;
34import static org.onosproject.kubevirtnode.api.Constants.GRE;
35import static org.onosproject.kubevirtnode.api.Constants.VXLAN;
36import static org.onosproject.net.AnnotationKeys.PORT_NAME;
Jian Li43dc9ca2020-12-19 04:01:49 +090037
38/**
39 * Representation of a KubeVirt node.
40 */
41public class DefaultKubevirtNode implements KubevirtNode {
42
43 private static final String NOT_NULL_MSG = "Node % cannot be null";
44 private static final String OVSDB = "ovsdb:";
45
46 private final String clusterName;
47 private final String hostname;
48 private final Type type;
49 private final DeviceId intgBridge;
Jian Li138f51f2021-01-06 03:29:58 +090050 private final DeviceId tunBridge;
Jian Li43dc9ca2020-12-19 04:01:49 +090051 private final IpAddress managementIp;
52 private final IpAddress dataIp;
53 private final KubevirtNodeState state;
54 private final Collection<KubevirtPhyInterface> phyIntfs;
55
56 /**
57 * A default constructor of kubevirt node.
58 *
59 * @param clusterName clusterName
60 * @param hostname hostname
61 * @param type node type
62 * @param intgBridge integration bridge
Jian Li138f51f2021-01-06 03:29:58 +090063 * @param tunBridge tunnel bridge
Jian Li43dc9ca2020-12-19 04:01:49 +090064 * @param managementIp management IP address
65 * @param dataIp data IP address
66 * @param state node state
67 * @param phyIntfs physical interfaces
68 */
69 protected DefaultKubevirtNode(String clusterName, String hostname, Type type,
Jian Li138f51f2021-01-06 03:29:58 +090070 DeviceId intgBridge, DeviceId tunBridge,
71 IpAddress managementIp, IpAddress dataIp,
72 KubevirtNodeState state,
Jian Li43dc9ca2020-12-19 04:01:49 +090073 Collection<KubevirtPhyInterface> phyIntfs) {
74 this.clusterName = clusterName;
75 this.hostname = hostname;
76 this.type = type;
77 this.intgBridge = intgBridge;
Jian Li138f51f2021-01-06 03:29:58 +090078 this.tunBridge = tunBridge;
Jian Li43dc9ca2020-12-19 04:01:49 +090079 this.managementIp = managementIp;
80 this.dataIp = dataIp;
81 this.state = state;
82 this.phyIntfs = phyIntfs;
83 }
84
85 @Override
86 public String clusterName() {
87 return clusterName;
88 }
89
90 @Override
91 public String hostname() {
92 return hostname;
93 }
94
95 @Override
96 public Type type() {
97 return type;
98 }
99
100 @Override
101 public DeviceId ovsdb() {
102 return DeviceId.deviceId(OVSDB + managementIp().toString());
103 }
104
105 @Override
106 public DeviceId intgBridge() {
107 return intgBridge;
108 }
109
110 @Override
Jian Li138f51f2021-01-06 03:29:58 +0900111 public DeviceId tunBridge() {
112 return tunBridge;
113 }
114
115 @Override
Jian Li43dc9ca2020-12-19 04:01:49 +0900116 public IpAddress managementIp() {
117 return managementIp;
118 }
119
120 @Override
121 public IpAddress dataIp() {
122 return dataIp;
123 }
124
125 @Override
126 public KubevirtNodeState state() {
127 return state;
128 }
129
130 @Override
131 public KubevirtNode updateState(KubevirtNodeState newState) {
132 return new Builder()
133 .hostname(hostname)
134 .clusterName(clusterName)
135 .type(type)
136 .intgBridge(intgBridge)
Jian Li138f51f2021-01-06 03:29:58 +0900137 .tunBridge(tunBridge)
Jian Li43dc9ca2020-12-19 04:01:49 +0900138 .managementIp(managementIp)
139 .dataIp(dataIp)
140 .state(newState)
141 .phyIntfs(phyIntfs)
142 .build();
143 }
144
145 @Override
Jian Li7c4a8822020-12-21 11:25:12 +0900146 public KubevirtNode updateIntgBridge(DeviceId deviceId) {
147 return new Builder()
148 .hostname(hostname)
149 .clusterName(clusterName)
150 .type(type)
151 .intgBridge(deviceId)
Jian Li138f51f2021-01-06 03:29:58 +0900152 .tunBridge(tunBridge)
153 .managementIp(managementIp)
154 .dataIp(dataIp)
155 .state(state)
156 .phyIntfs(phyIntfs)
157 .build();
158 }
159
160 @Override
161 public KubevirtNode updateTunBridge(DeviceId deviceId) {
162 return new Builder()
163 .hostname(hostname)
164 .clusterName(clusterName)
165 .type(type)
166 .intgBridge(intgBridge)
167 .tunBridge(deviceId)
Jian Li7c4a8822020-12-21 11:25:12 +0900168 .managementIp(managementIp)
169 .dataIp(dataIp)
170 .state(state)
171 .phyIntfs(phyIntfs)
172 .build();
173 }
174
175 @Override
Jian Li43dc9ca2020-12-19 04:01:49 +0900176 public Collection<KubevirtPhyInterface> phyIntfs() {
177 if (phyIntfs == null) {
178 return new ArrayList<>();
179 }
180
181 return phyIntfs;
182 }
183
Jian Li543fe852021-02-04 17:25:01 +0900184 @Override
185 public PortNumber vxlanPort() {
186 return tunnelPort(VXLAN);
187 }
188
189 @Override
190 public PortNumber grePort() {
191 return tunnelPort(GRE);
192 }
193
194 @Override
195 public PortNumber genevePort() {
196 return tunnelPort(GENEVE);
197 }
198
199 private PortNumber tunnelPort(String tunnelType) {
200 if (dataIp == null) {
201 return null;
202 }
203 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
204 Port port = deviceService.getPorts(tunBridge).stream()
205 .filter(p -> p.isEnabled() &&
206 Objects.equals(p.annotations().value(PORT_NAME), tunnelType))
207 .findAny().orElse(null);
208 return port != null ? port.number() : null;
209 }
210
Jian Li43dc9ca2020-12-19 04:01:49 +0900211 /**
212 * Returns new builder instance.
213 *
214 * @return kubevirt node builder
215 */
216 public static Builder builder() {
217 return new Builder();
218 }
219
220 /**
221 * Returns new builder instance with the given node as a default value.
222 *
223 * @param node kubevirt node
224 * @return kubevirt node builder
225 */
226 public static Builder from(KubevirtNode node) {
227 return new Builder()
228 .hostname(node.hostname())
229 .clusterName(node.clusterName())
230 .type(node.type())
231 .intgBridge(node.intgBridge())
Jian Li138f51f2021-01-06 03:29:58 +0900232 .tunBridge(node.tunBridge())
Jian Li43dc9ca2020-12-19 04:01:49 +0900233 .managementIp(node.managementIp())
234 .dataIp(node.dataIp())
Jian Li138f51f2021-01-06 03:29:58 +0900235 .state(node.state())
236 .phyIntfs(node.phyIntfs());
Jian Li43dc9ca2020-12-19 04:01:49 +0900237 }
238
239 @Override
240 public boolean equals(Object o) {
241 if (this == o) {
242 return true;
243 }
244 if (o == null || getClass() != o.getClass()) {
245 return false;
246 }
247 DefaultKubevirtNode that = (DefaultKubevirtNode) o;
248 return clusterName.equals(that.clusterName) &&
249 hostname.equals(that.hostname) &&
250 type == that.type &&
251 intgBridge.equals(that.intgBridge) &&
Jian Li138f51f2021-01-06 03:29:58 +0900252 tunBridge.equals(that.tunBridge) &&
Jian Li43dc9ca2020-12-19 04:01:49 +0900253 managementIp.equals(that.managementIp) &&
254 dataIp.equals(that.dataIp);
255 }
256
257 @Override
258 public int hashCode() {
Jian Li138f51f2021-01-06 03:29:58 +0900259 return Objects.hash(clusterName, hostname, type, intgBridge, tunBridge,
Jian Li43dc9ca2020-12-19 04:01:49 +0900260 managementIp, dataIp);
261 }
262
263 @Override
264 public String toString() {
265 return MoreObjects.toStringHelper(this)
266 .add("clusterName", clusterName)
267 .add("hostname", hostname)
268 .add("type", type)
269 .add("intgBridge", intgBridge)
Jian Li138f51f2021-01-06 03:29:58 +0900270 .add("tunBridge", tunBridge)
Jian Li43dc9ca2020-12-19 04:01:49 +0900271 .add("managementIp", managementIp)
272 .add("dataIp", dataIp)
273 .add("state", state)
Jian Li138f51f2021-01-06 03:29:58 +0900274 .add("phyIntfs", phyIntfs)
Jian Li43dc9ca2020-12-19 04:01:49 +0900275 .toString();
276 }
277
278 public static final class Builder implements KubevirtNode.Builder {
279
280 private String clusterName;
281 private String hostname;
282 private Type type;
283 private DeviceId intgBridge;
Jian Li138f51f2021-01-06 03:29:58 +0900284 private DeviceId tunBridge;
Jian Li43dc9ca2020-12-19 04:01:49 +0900285 private IpAddress managementIp;
286 private IpAddress dataIp;
287 private KubevirtNodeState state;
288 private Collection<KubevirtPhyInterface> phyIntfs;
289
290 // private constructor not intended to use from external
291 private Builder() {
292 }
293
294 @Override
295 public KubevirtNode build() {
296 checkArgument(hostname != null, NOT_NULL_MSG, "hostname");
297 checkArgument(type != null, NOT_NULL_MSG, "type");
298 checkArgument(state != null, NOT_NULL_MSG, "state");
299 checkArgument(managementIp != null, NOT_NULL_MSG, "management IP");
300
301 if (StringUtils.isEmpty(clusterName)) {
302 clusterName = DEFAULT_CLUSTER_NAME;
303 }
304
305 return new DefaultKubevirtNode(
306 clusterName,
307 hostname,
308 type,
309 intgBridge,
Jian Li138f51f2021-01-06 03:29:58 +0900310 tunBridge,
Jian Li43dc9ca2020-12-19 04:01:49 +0900311 managementIp,
312 dataIp,
313 state,
314 phyIntfs
315 );
316 }
317
318 @Override
319 public Builder clusterName(String clusterName) {
320 this.clusterName = clusterName;
321 return this;
322 }
323
324 @Override
325 public Builder hostname(String hostname) {
326 this.hostname = hostname;
327 return this;
328 }
329
330 @Override
331 public Builder type(Type type) {
332 this.type = type;
333 return this;
334 }
335
336 @Override
337 public Builder intgBridge(DeviceId deviceId) {
338 this.intgBridge = deviceId;
339 return this;
340 }
341
342 @Override
Jian Li138f51f2021-01-06 03:29:58 +0900343 public Builder tunBridge(DeviceId deviceId) {
344 this.tunBridge = deviceId;
345 return this;
346 }
347
348 @Override
Jian Li43dc9ca2020-12-19 04:01:49 +0900349 public Builder managementIp(IpAddress managementIp) {
350 this.managementIp = managementIp;
351 return this;
352 }
353
354 @Override
355 public Builder dataIp(IpAddress dataIp) {
356 this.dataIp = dataIp;
357 return this;
358 }
359
360 @Override
361 public Builder phyIntfs(Collection<KubevirtPhyInterface> phyIntfs) {
362 this.phyIntfs = phyIntfs;
363 return this;
364 }
365
366 @Override
367 public Builder state(KubevirtNodeState state) {
368 this.state = state;
369 return this;
370 }
371 }
372}