blob: 3fe7e4b466a3a5d1426627d54b209aef837bd18f [file] [log] [blame]
Charles Chan5270ed02016-01-30 23:22:37 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Charles Chan5270ed02016-01-30 23:22:37 -08003 *
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 */
16
17package org.onosproject.segmentrouting.config;
18
19import com.fasterxml.jackson.databind.JsonNode;
20import com.fasterxml.jackson.databind.node.ArrayNode;
21import com.google.common.collect.ImmutableSet;
22import org.onlab.packet.MacAddress;
23import org.onosproject.core.ApplicationId;
Charles Chand9681e72016-02-22 19:27:29 -080024import org.onosproject.net.ConnectPoint;
Charles Chanf2565a92016-02-10 20:46:58 -080025import org.onosproject.net.DeviceId;
Charles Chan5270ed02016-01-30 23:22:37 -080026import org.onosproject.net.config.Config;
Charles Chand9681e72016-02-22 19:27:29 -080027
28import java.util.Optional;
Charles Chan5270ed02016-01-30 23:22:37 -080029import java.util.Set;
30
31import static com.google.common.base.MoreObjects.toStringHelper;
32
33/**
34 * App configuration object for Segment Routing.
35 */
36public class SegmentRoutingAppConfig extends Config<ApplicationId> {
37 private static final String VROUTER_MACS = "vRouterMacs";
Charles Chanf2565a92016-02-10 20:46:58 -080038 private static final String VROUTER_ID = "vRouterId";
Charles Chand9681e72016-02-22 19:27:29 -080039 private static final String SUPPRESS_SUBNET = "suppressSubnet";
Charles Chanb3007e12016-05-20 10:55:40 -070040 private static final String SUPPRESS_HOST_BY_PORT = "suppressHostByPort";
41 // TODO We might want to move SUPPRESS_HOST_BY_PROVIDER to Component Config
42 private static final String SUPPRESS_HOST_BY_PROVIDER = "suppressHostByProvider";
Pier Ventre98161782016-10-31 15:00:01 -070043 private static final String MPLS_ECMP = "MPLS-ECMP";
Charles Chan5270ed02016-01-30 23:22:37 -080044
45 @Override
46 public boolean isValid() {
Charles Chan6ea94fc2016-05-10 17:29:47 -070047 return hasOnlyFields(VROUTER_MACS, VROUTER_ID, SUPPRESS_SUBNET,
Pier Ventre98161782016-10-31 15:00:01 -070048 SUPPRESS_HOST_BY_PORT, SUPPRESS_HOST_BY_PROVIDER, MPLS_ECMP) &&
Charles Chanf2565a92016-02-10 20:46:58 -080049 vRouterMacs() != null && vRouterId() != null &&
Charles Chanb3007e12016-05-20 10:55:40 -070050 suppressSubnet() != null && suppressHostByPort() != null &&
51 suppressHostByProvider() != null;
Charles Chan5270ed02016-01-30 23:22:37 -080052 }
53
54 /**
Pier Ventre98161782016-10-31 15:00:01 -070055 * Gets MPLS-ECMP configuration from the config.
56 *
57 * @return the configuration of MPLS-ECMP. If it is not
58 * specified, the default behavior is false.
59 */
60 public boolean mplsEcmp() {
61 return get(MPLS_ECMP, false);
62 }
63
64 /**
65 * Sets MPLS-ECMP to the config.
66 *
67 * @param mplsEcmp the MPLS-ECMP configuration
68 * @return this {@link SegmentRoutingAppConfig}
69 */
70 public SegmentRoutingAppConfig setMplsEcmp(boolean mplsEcmp) {
71 object.put(MPLS_ECMP, mplsEcmp);
72 return this;
73 }
74
75 /**
Charles Chan5270ed02016-01-30 23:22:37 -080076 * Gets vRouters from the config.
77 *
Charles Chand9681e72016-02-22 19:27:29 -080078 * @return Set of vRouter MAC addresses, empty is not specified,
79 * or null if not valid
Charles Chan5270ed02016-01-30 23:22:37 -080080 */
81 public Set<MacAddress> vRouterMacs() {
82 if (!object.has(VROUTER_MACS)) {
Charles Chand9681e72016-02-22 19:27:29 -080083 return ImmutableSet.of();
Charles Chan5270ed02016-01-30 23:22:37 -080084 }
85
86 ImmutableSet.Builder<MacAddress> builder = ImmutableSet.builder();
87 ArrayNode arrayNode = (ArrayNode) object.path(VROUTER_MACS);
88 for (JsonNode jsonNode : arrayNode) {
89 MacAddress mac;
90
91 String macStr = jsonNode.asText(null);
92 if (macStr == null) {
93 return null;
94 }
95 try {
96 mac = MacAddress.valueOf(macStr);
97 } catch (IllegalArgumentException e) {
98 return null;
99 }
100
101 builder.add(mac);
102 }
103 return builder.build();
104 }
105
106 /**
107 * Sets vRouters to the config.
108 *
109 * @param vRouterMacs a set of vRouter MAC addresses
110 * @return this {@link SegmentRoutingAppConfig}
111 */
112 public SegmentRoutingAppConfig setVRouterMacs(Set<MacAddress> vRouterMacs) {
113 if (vRouterMacs == null) {
114 object.remove(VROUTER_MACS);
115 } else {
116 ArrayNode arrayNode = mapper.createArrayNode();
117
118 vRouterMacs.forEach(mac -> {
119 arrayNode.add(mac.toString());
120 });
121
122 object.set(VROUTER_MACS, arrayNode);
123 }
124 return this;
125 }
126
Charles Chanf2565a92016-02-10 20:46:58 -0800127 /**
128 * Gets vRouter device ID.
129 *
Charles Chand9681e72016-02-22 19:27:29 -0800130 * @return Optional vRouter device ID,
131 * empty is not specified or null if not valid
Charles Chanf2565a92016-02-10 20:46:58 -0800132 */
Charles Chand9681e72016-02-22 19:27:29 -0800133 public Optional<DeviceId> vRouterId() {
Charles Chanf2565a92016-02-10 20:46:58 -0800134 if (!object.has(VROUTER_ID)) {
Charles Chand9681e72016-02-22 19:27:29 -0800135 return Optional.empty();
Charles Chanf2565a92016-02-10 20:46:58 -0800136 }
137
138 try {
Charles Chand9681e72016-02-22 19:27:29 -0800139 return Optional.of(DeviceId.deviceId(object.path(VROUTER_ID).asText()));
Charles Chanf2565a92016-02-10 20:46:58 -0800140 } catch (IllegalArgumentException e) {
141 return null;
142 }
143 }
144
145 /**
146 * Sets vRouter device ID.
147 *
148 * @param vRouterId vRouter device ID
149 * @return this {@link SegmentRoutingAppConfig}
150 */
151 public SegmentRoutingAppConfig setVRouterId(DeviceId vRouterId) {
152 if (vRouterId == null) {
153 object.remove(VROUTER_ID);
154 } else {
155 object.put(VROUTER_ID, vRouterId.toString());
156 }
157 return this;
158 }
159
160 /**
Charles Chand9681e72016-02-22 19:27:29 -0800161 * Gets names of ports to which SegmentRouting does not push subnet rules.
Charles Chanf2565a92016-02-10 20:46:58 -0800162 *
Charles Chand9681e72016-02-22 19:27:29 -0800163 * @return Set of port names, empty if not specified, or null
164 * if not valid
Charles Chanf2565a92016-02-10 20:46:58 -0800165 */
Charles Chand9681e72016-02-22 19:27:29 -0800166 public Set<ConnectPoint> suppressSubnet() {
167 if (!object.has(SUPPRESS_SUBNET)) {
168 return ImmutableSet.of();
Charles Chanf2565a92016-02-10 20:46:58 -0800169 }
170
Charles Chand9681e72016-02-22 19:27:29 -0800171 ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
172 ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_SUBNET);
Charles Chanf2565a92016-02-10 20:46:58 -0800173 for (JsonNode jsonNode : arrayNode) {
174 String portName = jsonNode.asText(null);
175 if (portName == null) {
176 return null;
177 }
Charles Chand9681e72016-02-22 19:27:29 -0800178 try {
179 builder.add(ConnectPoint.deviceConnectPoint(portName));
180 } catch (IllegalArgumentException e) {
181 return null;
182 }
Charles Chanf2565a92016-02-10 20:46:58 -0800183 }
184 return builder.build();
185 }
186
187 /**
Charles Chand9681e72016-02-22 19:27:29 -0800188 * Sets names of ports to which SegmentRouting does not push subnet rules.
Charles Chanf2565a92016-02-10 20:46:58 -0800189 *
Charles Chand9681e72016-02-22 19:27:29 -0800190 * @param suppressSubnet names of ports to which SegmentRouting does not push
191 * subnet rules
Charles Chanf2565a92016-02-10 20:46:58 -0800192 * @return this {@link SegmentRoutingAppConfig}
193 */
Charles Chand9681e72016-02-22 19:27:29 -0800194 public SegmentRoutingAppConfig setSuppressSubnet(Set<ConnectPoint> suppressSubnet) {
195 if (suppressSubnet == null) {
196 object.remove(SUPPRESS_SUBNET);
Charles Chanf2565a92016-02-10 20:46:58 -0800197 } else {
198 ArrayNode arrayNode = mapper.createArrayNode();
Charles Chand9681e72016-02-22 19:27:29 -0800199 suppressSubnet.forEach(connectPoint -> {
200 arrayNode.add(connectPoint.deviceId() + "/" + connectPoint.port());
Charles Chanf2565a92016-02-10 20:46:58 -0800201 });
Charles Chand9681e72016-02-22 19:27:29 -0800202 object.set(SUPPRESS_SUBNET, arrayNode);
203 }
204 return this;
205 }
206
207 /**
Charles Chanb3007e12016-05-20 10:55:40 -0700208 * Gets connect points to which SegmentRouting does not push host rules.
Charles Chand9681e72016-02-22 19:27:29 -0800209 *
Charles Chanb3007e12016-05-20 10:55:40 -0700210 * @return Set of connect points, empty if not specified, or null
Charles Chand9681e72016-02-22 19:27:29 -0800211 * if not valid
212 */
Charles Chanb3007e12016-05-20 10:55:40 -0700213 public Set<ConnectPoint> suppressHostByPort() {
214 if (!object.has(SUPPRESS_HOST_BY_PORT)) {
Charles Chand9681e72016-02-22 19:27:29 -0800215 return ImmutableSet.of();
216 }
217
218 ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
Charles Chanb3007e12016-05-20 10:55:40 -0700219 ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_HOST_BY_PORT);
Charles Chand9681e72016-02-22 19:27:29 -0800220 for (JsonNode jsonNode : arrayNode) {
221 String portName = jsonNode.asText(null);
222 if (portName == null) {
223 return null;
224 }
225 try {
226 builder.add(ConnectPoint.deviceConnectPoint(portName));
227 } catch (IllegalArgumentException e) {
228 return null;
229 }
230 }
231 return builder.build();
232 }
233
234 /**
Charles Chanb3007e12016-05-20 10:55:40 -0700235 * Sets connect points to which SegmentRouting does not push host rules.
Charles Chand9681e72016-02-22 19:27:29 -0800236 *
Charles Chanb3007e12016-05-20 10:55:40 -0700237 * @param connectPoints connect points to which SegmentRouting does not push
Charles Chand9681e72016-02-22 19:27:29 -0800238 * host rules
239 * @return this {@link SegmentRoutingAppConfig}
240 */
Charles Chanb3007e12016-05-20 10:55:40 -0700241 public SegmentRoutingAppConfig setSuppressHostByPort(Set<ConnectPoint> connectPoints) {
242 if (connectPoints == null) {
243 object.remove(SUPPRESS_HOST_BY_PORT);
Charles Chand9681e72016-02-22 19:27:29 -0800244 } else {
245 ArrayNode arrayNode = mapper.createArrayNode();
Charles Chanb3007e12016-05-20 10:55:40 -0700246 connectPoints.forEach(connectPoint -> {
Charles Chand9681e72016-02-22 19:27:29 -0800247 arrayNode.add(connectPoint.deviceId() + "/" + connectPoint.port());
248 });
Charles Chanb3007e12016-05-20 10:55:40 -0700249 object.set(SUPPRESS_HOST_BY_PORT, arrayNode);
Charles Chanf2565a92016-02-10 20:46:58 -0800250 }
251 return this;
252 }
253
Charles Chan6ea94fc2016-05-10 17:29:47 -0700254 /**
Charles Chanb3007e12016-05-20 10:55:40 -0700255 * Gets provider names from which SegmentRouting does not learn host info.
Charles Chan6ea94fc2016-05-10 17:29:47 -0700256 *
Charles Chanb3007e12016-05-20 10:55:40 -0700257 * @return array of provider names that need to be ignored
Charles Chan6ea94fc2016-05-10 17:29:47 -0700258 */
Charles Chanb3007e12016-05-20 10:55:40 -0700259 public Set<String> suppressHostByProvider() {
260 if (!object.has(SUPPRESS_HOST_BY_PROVIDER)) {
261 return ImmutableSet.of();
262 }
263
264 ImmutableSet.Builder<String> builder = ImmutableSet.builder();
265 ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_HOST_BY_PROVIDER);
266 for (JsonNode jsonNode : arrayNode) {
267 String providerName = jsonNode.asText(null);
268 if (providerName == null) {
269 return null;
270 }
271 builder.add(providerName);
272 }
273 return builder.build();
Charles Chan6ea94fc2016-05-10 17:29:47 -0700274 }
275
276 /**
Charles Chanb3007e12016-05-20 10:55:40 -0700277 * Sets provider names from which SegmentRouting does not learn host info.
Charles Chan6ea94fc2016-05-10 17:29:47 -0700278 *
Charles Chanb3007e12016-05-20 10:55:40 -0700279 * @param providers set of provider names
Charles Chan6ea94fc2016-05-10 17:29:47 -0700280 * @return this {@link SegmentRoutingAppConfig}
281 */
Charles Chanb3007e12016-05-20 10:55:40 -0700282 public SegmentRoutingAppConfig setSuppressHostByProvider(Set<String> providers) {
283 if (providers == null) {
284 object.remove(SUPPRESS_HOST_BY_PROVIDER);
285 } else {
286 ArrayNode arrayNode = mapper.createArrayNode();
287 providers.forEach(arrayNode::add);
288 object.set(SUPPRESS_HOST_BY_PROVIDER, arrayNode);
289 }
Charles Chan6ea94fc2016-05-10 17:29:47 -0700290 return this;
291 }
292
Charles Chan5270ed02016-01-30 23:22:37 -0800293 @Override
294 public String toString() {
295 return toStringHelper(this)
296 .add("vRouterMacs", vRouterMacs())
Charles Chand9681e72016-02-22 19:27:29 -0800297 .add("vRouterId", vRouterId())
298 .add("suppressSubnet", suppressSubnet())
Charles Chanb3007e12016-05-20 10:55:40 -0700299 .add("suppressHostByPort", suppressHostByPort())
300 .add("suppressHostByProvider", suppressHostByProvider())
Pier Ventre98161782016-10-31 15:00:01 -0700301 .add("mplsEcmp", mplsEcmp())
Charles Chan5270ed02016-01-30 23:22:37 -0800302 .toString();
303 }
304}