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