blob: 3e26a50d81390bc83b35173aef8a067a1cd1e960 [file] [log] [blame]
Jian Li49109b52019-01-22 00:17:28 +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.api;
17
18import com.google.common.base.MoreObjects;
19import org.onlab.osgi.DefaultServiceDirectory;
20import org.onlab.packet.IpAddress;
21import org.onosproject.net.DeviceId;
22import org.onosproject.net.Port;
23import org.onosproject.net.PortNumber;
24import org.onosproject.net.device.DeviceService;
25
26import java.util.Objects;
27
28import static com.google.common.base.Preconditions.checkArgument;
29import static org.onosproject.k8snode.api.Constants.GENEVE_TUNNEL;
30import static org.onosproject.k8snode.api.Constants.GRE_TUNNEL;
Jian Li4aa17642019-01-30 00:01:11 +090031import static org.onosproject.k8snode.api.Constants.INTEGRATION_BRIDGE;
Jian Li49109b52019-01-22 00:17:28 +090032import static org.onosproject.k8snode.api.Constants.VXLAN_TUNNEL;
33import static org.onosproject.net.AnnotationKeys.PORT_NAME;
34
35/**
36 * Representation of a kubernetes node.
37 */
38public class DefaultK8sNode implements K8sNode {
39
40 private final String hostname;
41 private final Type type;
42 private final DeviceId intgBridge;
43 private final IpAddress managementIp;
44 private final IpAddress dataIp;
45 private final K8sNodeState state;
46
47 private static final String NOT_NULL_MSG = "Node % cannot be null";
48
49 private static final String OVSDB = "ovsdb:";
50
51 /**
52 * A default constructor of kubernetes Node.
53 *
54 * @param hostname hostname
55 * @param type node type
56 * @param intgBridge integration bridge
57 * @param managementIp management IP address
58 * @param dataIp data IP address
59 * @param state node state
60 */
61 protected DefaultK8sNode(String hostname, Type type, DeviceId intgBridge,
Jian Li3defa842019-02-12 00:31:35 +090062 IpAddress managementIp, IpAddress dataIp,
63 K8sNodeState state) {
Jian Li49109b52019-01-22 00:17:28 +090064 this.hostname = hostname;
65 this.type = type;
66 this.intgBridge = intgBridge;
67 this.managementIp = managementIp;
68 this.dataIp = dataIp;
69 this.state = state;
70 }
71
72 @Override
73 public String hostname() {
74 return hostname;
75 }
76
77 @Override
78 public Type type() {
79 return type;
80 }
81
82 @Override
83 public DeviceId ovsdb() {
84 return DeviceId.deviceId(OVSDB + managementIp().toString());
85 }
86
87 @Override
88 public DeviceId intgBridge() {
89 return intgBridge;
90 }
91
92 @Override
Jian Li1cee9882019-02-13 11:25:25 +090093 public K8sNode updateIntgBridge(DeviceId deviceId) {
94 return new Builder()
95 .hostname(hostname)
96 .type(type)
97 .intgBridge(deviceId)
98 .managementIp(managementIp)
99 .dataIp(dataIp)
100 .state(state)
101 .build();
102 }
103
104 @Override
Jian Li49109b52019-01-22 00:17:28 +0900105 public IpAddress managementIp() {
106 return managementIp;
107 }
108
109 @Override
110 public IpAddress dataIp() {
111 return dataIp;
112 }
113
114 @Override
115 public K8sNodeState state() {
116 return state;
117 }
118
119 @Override
120 public K8sNode updateState(K8sNodeState newState) {
121 return new Builder()
122 .hostname(hostname)
123 .type(type)
124 .intgBridge(intgBridge)
125 .managementIp(managementIp)
126 .dataIp(dataIp)
127 .state(newState)
128 .build();
129 }
130
131 @Override
132 public PortNumber grePortNum() {
133 return tunnelPortNum(GRE_TUNNEL);
134 }
135
136 @Override
137 public PortNumber vxlanPortNum() {
138 return tunnelPortNum(VXLAN_TUNNEL);
139 }
140
141 @Override
142 public PortNumber genevePortNum() {
143 return tunnelPortNum(GENEVE_TUNNEL);
144 }
145
146 @Override
Jian Li4aa17642019-01-30 00:01:11 +0900147 public PortNumber intBridgePortNum() {
148 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
149 Port port = deviceService.getPorts(intgBridge).stream()
150 .filter(p -> p.isEnabled() &&
151 Objects.equals(p.annotations().value(PORT_NAME), INTEGRATION_BRIDGE))
152 .findAny().orElse(null);
153 return port != null ? port.number() : null;
154 }
155
156 @Override
Jian Li49109b52019-01-22 00:17:28 +0900157 public boolean equals(Object obj) {
158 if (this == obj) {
159 return true;
160 }
161
162 if (obj instanceof DefaultK8sNode) {
163 DefaultK8sNode that = (DefaultK8sNode) obj;
164
165 return hostname.equals(that.hostname) &&
166 type == that.type &&
167 intgBridge.equals(that.intgBridge) &&
168 managementIp.equals(that.managementIp) &&
169 dataIp.equals(that.dataIp) &&
170 state == that.state;
171 }
172
173 return false;
174 }
175
176 @Override
177 public int hashCode() {
178 return Objects.hash(hostname, type, intgBridge, managementIp, dataIp, state);
179 }
180
181 @Override
182 public String toString() {
183 return MoreObjects.toStringHelper(this)
184 .add("hostname", hostname)
185 .add("type", type)
186 .add("intgBridge", intgBridge)
187 .add("managementIp", managementIp)
188 .add("dataIp", dataIp)
189 .add("state", state)
190 .toString();
191 }
192
193 private PortNumber tunnelPortNum(String tunnelType) {
194 if (dataIp == null) {
195 return null;
196 }
197 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
198 Port port = deviceService.getPorts(intgBridge).stream()
199 .filter(p -> p.isEnabled() &&
200 Objects.equals(p.annotations().value(PORT_NAME), tunnelType))
201 .findAny().orElse(null);
202 return port != null ? port.number() : null;
203 }
204
205 /**
206 * Returns new builder instance.
207 *
208 * @return kubernetes node builder
209 */
210 public static Builder builder() {
211 return new Builder();
212 }
213
214 /**
215 * Returns new builder instance with the given node as a default value.
216 *
217 * @param node kubernetes node
218 * @return kubernetes node builder
219 */
220 public static Builder from(K8sNode node) {
221 return new Builder()
222 .hostname(node.hostname())
223 .type(node.type())
224 .intgBridge(node.intgBridge())
225 .managementIp(node.managementIp())
226 .dataIp(node.dataIp())
227 .state(node.state());
228 }
229
230 public static final class Builder implements K8sNode.Builder {
231
232 private String hostname;
233 private Type type;
234 private DeviceId intgBridge;
235 private IpAddress managementIp;
236 private IpAddress dataIp;
237 private K8sNodeState state;
Jian Li3defa842019-02-12 00:31:35 +0900238 private K8sApiConfig apiConfig;
Jian Li49109b52019-01-22 00:17:28 +0900239
240 // private constructor not intended to use from external
241 private Builder() {
242 }
243
244 @Override
245 public K8sNode build() {
246 checkArgument(hostname != null, NOT_NULL_MSG, "hostname");
247 checkArgument(type != null, NOT_NULL_MSG, "type");
248 checkArgument(state != null, NOT_NULL_MSG, "state");
249 checkArgument(managementIp != null, NOT_NULL_MSG, "management IP");
250
251 return new DefaultK8sNode(hostname,
252 type,
253 intgBridge,
254 managementIp,
255 dataIp,
256 state);
257 }
258
259 @Override
260 public Builder hostname(String hostname) {
261 this.hostname = hostname;
262 return this;
263 }
264
265 @Override
266 public Builder type(Type type) {
267 this.type = type;
268 return this;
269 }
270
271 @Override
272 public Builder intgBridge(DeviceId deviceId) {
273 this.intgBridge = deviceId;
274 return this;
275 }
276
277 @Override
278 public Builder managementIp(IpAddress managementIp) {
279 this.managementIp = managementIp;
280 return this;
281 }
282
283 @Override
284 public Builder dataIp(IpAddress dataIp) {
285 this.dataIp = dataIp;
286 return this;
287 }
288
289 @Override
290 public Builder state(K8sNodeState state) {
291 this.state = state;
292 return this;
293 }
294 }
295}