blob: f62000e3823faee9d5124eb9a95922fe24205a38 [file] [log] [blame]
sdnb0302912018-06-07 15:44:10 +09001/*
2 * Copyright 2018-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 */
16
17package org.onosproject.drivers.cisco.rest;
18
19import static org.slf4j.LoggerFactory.getLogger;
20
Ray Milkey61b4c342018-06-08 09:36:57 -070021import java.io.IOException;
sdnb0302912018-06-07 15:44:10 +090022import java.util.ArrayList;
23import java.util.List;
24import java.util.Objects;
sdn4eae2982018-06-10 17:39:11 +090025import java.util.regex.Matcher;
26import java.util.regex.Pattern;
sdnb0302912018-06-07 15:44:10 +090027
sdn4eae2982018-06-10 17:39:11 +090028import org.onlab.packet.IpAddress;
sdnb0302912018-06-07 15:44:10 +090029import org.onosproject.drivers.cisco.rest.NxApiRequest.CommandType;
30import org.onosproject.net.DeviceId;
31import org.onosproject.net.behaviour.ControllerConfig;
32import org.onosproject.net.behaviour.ControllerInfo;
33import org.onosproject.net.driver.AbstractHandlerBehaviour;
34import org.onosproject.net.driver.DriverHandler;
35import org.slf4j.Logger;
36
37import com.fasterxml.jackson.databind.JsonNode;
38import com.fasterxml.jackson.databind.ObjectMapper;
39
40/**
41 * Gets and Sets the openflow controller.
42 */
43public class ControllerConfigCiscoImpl extends AbstractHandlerBehaviour implements ControllerConfig {
44 private final Logger log = getLogger(getClass());
45
46 private static final String SHOW_OF_CONTROLLER_CMD = "show openflow switch 1 controllers";
47 private static final String OPENFLOW_CMD = "openflow";
48 private static final String SW1_CMD = "switch 1";
49 private static final String DELETE_OF_CONFIG = "no switch 1";
50 private static final String PROTO_VER_CMD = "protocol-version 1.3";
sdn6057fab2018-06-21 13:37:42 +090051 private static final String N9K_PIPELINE_CMD = "pipeline 201";
52 private static final String N7K_PIPELINE_CMD = "pipeline 301";
sdnb0302912018-06-07 15:44:10 +090053 private static final String OF_CONTROLLER_CONF_CMD = "controller ipv4 %s port %d vrf %s security none";
54 private static final String NO_SHUTDOWN_CMD = "no shutdown";
sdn6057fab2018-06-21 13:37:42 +090055 private static final String SHOW_VERSION = "show version";
sdnb0302912018-06-07 15:44:10 +090056 private static final String COPY_RUNNING_CONFIG = "copy running-config startup-config";
57
58 @Override
59 public List<ControllerInfo> getControllers() {
60 List<ControllerInfo> controllers = new ArrayList<ControllerInfo>();
61 DeviceId deviceId = handler().data().deviceId();
62
63 String response;
64
65 // "show openflow switch 1 controller" command only shows outputs with cli_ascii command type
66 response = NxApiRequest.post(handler(), SHOW_OF_CONTROLLER_CMD, CommandType.CLI_ASCII);
67
68 if (response == null) {
69 log.error("Failed to perform {} command on the device {} Response has Error/null",
70 SHOW_OF_CONTROLLER_CMD, deviceId);
71 return controllers;
72 }
73
74 try {
75 ObjectMapper om = new ObjectMapper();
76 JsonNode json = om.readTree(response);
77 if (json.has("result")) {
78 JsonNode res = json.get("result");
79 String msg = res.findValue("msg").asText();
sdn4eae2982018-06-10 17:39:11 +090080 controllers.addAll(parseControllerInfo(msg));
sdnb0302912018-06-07 15:44:10 +090081 } else if (json.has("error")) {
82 log.error("{} Response has IllegalStateException Error/null", deviceId);
83 return controllers;
84 }
85 } catch (IOException e) {
86 log.error("Exception thrown", e);
87 }
88
89 return controllers;
90 }
91
92 @Override
93 public void setControllers(List<ControllerInfo> controllers) {
94 DriverHandler handler = handler();
95 DeviceId deviceId = handler.data().deviceId();
96
97 List<String> cmds = new ArrayList<>();
98 cmds.add(OPENFLOW_CMD);
99 cmds.add(DELETE_OF_CONFIG);
100 cmds.add(SW1_CMD);
101 cmds.add(PROTO_VER_CMD);
sdn6057fab2018-06-21 13:37:42 +0900102 if (checkSwitchN7K(handler)) {
103 cmds.add(N7K_PIPELINE_CMD);
104 log.info("This is N7K Switch");
105 }
106 cmds.add(N9K_PIPELINE_CMD);
107 log.info("This is N9K Switch");
sdnb0302912018-06-07 15:44:10 +0900108
109 // can configure up to eight controllers
110 controllers.stream().limit(8).forEach(c -> cmds
111 .add(String.format(OF_CONTROLLER_CONF_CMD, c.ip().toString(), c.port(), "management")));
112 cmds.add(NO_SHUTDOWN_CMD);
113 cmds.add(COPY_RUNNING_CONFIG);
114 String response = NxApiRequest.postClis(handler, cmds);
115 if (Objects.isNull(response)) {
116 throw new NullPointerException("Response is null");
117 }
118
Ray Milkey4dda8142018-06-08 08:55:37 -0700119 try {
120 ObjectMapper om = new ObjectMapper();
121 JsonNode json = om.readTree(response);
122 //TODO parse error messages.
123 if (json.has("error")) {
124 log.error("{} Response has IllegalStateException Error", deviceId);
125 return;
sdnb0302912018-06-07 15:44:10 +0900126 }
Ray Milkey4dda8142018-06-08 08:55:37 -0700127 } catch (IOException e) {
128 log.error("Exception thrown", e);
sdnb0302912018-06-07 15:44:10 +0900129 }
130 }
sdn4eae2982018-06-10 17:39:11 +0900131
132 @Override
133 public void removeControllers(List<ControllerInfo> controllers) {
134 DriverHandler handler = handler();
135 DeviceId deviceId = handler.data().deviceId();
136
137 List<String> cmds = new ArrayList<>();
138 cmds.add(OPENFLOW_CMD);
139 cmds.add(DELETE_OF_CONFIG);
140 cmds.add(COPY_RUNNING_CONFIG);
141
142 String response = NxApiRequest.postClis(handler, cmds);
143 if (Objects.isNull(response)) {
144 log.error(" Device {} Response is null", deviceId);
145 return;
146 }
147
148 try {
149 ObjectMapper om = new ObjectMapper();
150 JsonNode json = om.readTree(response);
151 if (json.has("errors")) {
152 log.error("{} Response has JSON Format Error {}", deviceId, json);
153 return;
154 }
155 //TODO parse error messages.
156 } catch (IOException e) {
157 log.error("Exception thrown", e);
158 }
159 }
160
161 private List<ControllerInfo> parseControllerInfo(String data) {
162 final String regex = "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}):(\\d{1,5})";
163 Pattern pattern = Pattern.compile(regex);
164 Matcher match = pattern.matcher(data);
165 List<ControllerInfo> controllers = new ArrayList<ControllerInfo>();
166 while (match.find()) {
167 String str = match.group();
168 String[] ips = str.split(":");
169 ControllerInfo info = new ControllerInfo(IpAddress.valueOf(ips[0]),
170 Integer.parseInt(ips[1]), "tcp");
171 controllers.add(info);
172 }
173
174 return controllers;
175 }
176
177
sdn6057fab2018-06-21 13:37:42 +0900178 public boolean checkSwitchN7K(DriverHandler handler) {
179
180 String response = NxApiRequest.postClis(handler, SHOW_VERSION);
181
182 String msg = "";
183
184 try {
185 ObjectMapper om = new ObjectMapper();
186 JsonNode json = om.readTree(response);
187 JsonNode res = json.get("result");
188 msg = res.findValue("msg").asText();
189 } catch (IOException e) {
190 log.error("Exception thrown", e);
191 return false;
192 }
193
194 if (msg.contains("Nexus7700")) {
195 return true;
196 }
197 return false;
198 }
sdnb0302912018-06-07 15:44:10 +0900199}