blob: 76b845cd56eacaf5e5cec804716b485f29623da7 [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
93 public IpAddress managementIp() {
94 return managementIp;
95 }
96
97 @Override
98 public IpAddress dataIp() {
99 return dataIp;
100 }
101
102 @Override
103 public K8sNodeState state() {
104 return state;
105 }
106
107 @Override
108 public K8sNode updateState(K8sNodeState newState) {
109 return new Builder()
110 .hostname(hostname)
111 .type(type)
112 .intgBridge(intgBridge)
113 .managementIp(managementIp)
114 .dataIp(dataIp)
115 .state(newState)
116 .build();
117 }
118
119 @Override
120 public PortNumber grePortNum() {
121 return tunnelPortNum(GRE_TUNNEL);
122 }
123
124 @Override
125 public PortNumber vxlanPortNum() {
126 return tunnelPortNum(VXLAN_TUNNEL);
127 }
128
129 @Override
130 public PortNumber genevePortNum() {
131 return tunnelPortNum(GENEVE_TUNNEL);
132 }
133
134 @Override
Jian Li4aa17642019-01-30 00:01:11 +0900135 public PortNumber intBridgePortNum() {
136 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
137 Port port = deviceService.getPorts(intgBridge).stream()
138 .filter(p -> p.isEnabled() &&
139 Objects.equals(p.annotations().value(PORT_NAME), INTEGRATION_BRIDGE))
140 .findAny().orElse(null);
141 return port != null ? port.number() : null;
142 }
143
144 @Override
Jian Li49109b52019-01-22 00:17:28 +0900145 public boolean equals(Object obj) {
146 if (this == obj) {
147 return true;
148 }
149
150 if (obj instanceof DefaultK8sNode) {
151 DefaultK8sNode that = (DefaultK8sNode) obj;
152
153 return hostname.equals(that.hostname) &&
154 type == that.type &&
155 intgBridge.equals(that.intgBridge) &&
156 managementIp.equals(that.managementIp) &&
157 dataIp.equals(that.dataIp) &&
158 state == that.state;
159 }
160
161 return false;
162 }
163
164 @Override
165 public int hashCode() {
166 return Objects.hash(hostname, type, intgBridge, managementIp, dataIp, state);
167 }
168
169 @Override
170 public String toString() {
171 return MoreObjects.toStringHelper(this)
172 .add("hostname", hostname)
173 .add("type", type)
174 .add("intgBridge", intgBridge)
175 .add("managementIp", managementIp)
176 .add("dataIp", dataIp)
177 .add("state", state)
178 .toString();
179 }
180
181 private PortNumber tunnelPortNum(String tunnelType) {
182 if (dataIp == null) {
183 return null;
184 }
185 DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
186 Port port = deviceService.getPorts(intgBridge).stream()
187 .filter(p -> p.isEnabled() &&
188 Objects.equals(p.annotations().value(PORT_NAME), tunnelType))
189 .findAny().orElse(null);
190 return port != null ? port.number() : null;
191 }
192
193 /**
194 * Returns new builder instance.
195 *
196 * @return kubernetes node builder
197 */
198 public static Builder builder() {
199 return new Builder();
200 }
201
202 /**
203 * Returns new builder instance with the given node as a default value.
204 *
205 * @param node kubernetes node
206 * @return kubernetes node builder
207 */
208 public static Builder from(K8sNode node) {
209 return new Builder()
210 .hostname(node.hostname())
211 .type(node.type())
212 .intgBridge(node.intgBridge())
213 .managementIp(node.managementIp())
214 .dataIp(node.dataIp())
215 .state(node.state());
216 }
217
218 public static final class Builder implements K8sNode.Builder {
219
220 private String hostname;
221 private Type type;
222 private DeviceId intgBridge;
223 private IpAddress managementIp;
224 private IpAddress dataIp;
225 private K8sNodeState state;
Jian Li3defa842019-02-12 00:31:35 +0900226 private K8sApiConfig apiConfig;
Jian Li49109b52019-01-22 00:17:28 +0900227
228 // private constructor not intended to use from external
229 private Builder() {
230 }
231
232 @Override
233 public K8sNode build() {
234 checkArgument(hostname != null, NOT_NULL_MSG, "hostname");
235 checkArgument(type != null, NOT_NULL_MSG, "type");
236 checkArgument(state != null, NOT_NULL_MSG, "state");
237 checkArgument(managementIp != null, NOT_NULL_MSG, "management IP");
238
239 return new DefaultK8sNode(hostname,
240 type,
241 intgBridge,
242 managementIp,
243 dataIp,
244 state);
245 }
246
247 @Override
248 public Builder hostname(String hostname) {
249 this.hostname = hostname;
250 return this;
251 }
252
253 @Override
254 public Builder type(Type type) {
255 this.type = type;
256 return this;
257 }
258
259 @Override
260 public Builder intgBridge(DeviceId deviceId) {
261 this.intgBridge = deviceId;
262 return this;
263 }
264
265 @Override
266 public Builder managementIp(IpAddress managementIp) {
267 this.managementIp = managementIp;
268 return this;
269 }
270
271 @Override
272 public Builder dataIp(IpAddress dataIp) {
273 this.dataIp = dataIp;
274 return this;
275 }
276
277 @Override
278 public Builder state(K8sNodeState state) {
279 this.state = state;
280 return this;
281 }
282 }
283}