blob: 5d3001def84a2b1b9dd334a00f123874d57a3460 [file] [log] [blame]
Hyunsun Moonc7219222017-03-27 11:05:59 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Hyunsun Moonc7219222017-03-27 11:05:59 +09003 *
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.openstacknetworking.cli;
17
Hyunsun Moonc7219222017-03-27 11:05:59 +090018import com.google.common.base.Strings;
Ray Milkey86ad7bb2018-09-27 12:32:28 -070019import org.apache.karaf.shell.api.action.Command;
Ray Milkey7a2dee52018-09-28 10:58:28 -070020import org.apache.karaf.shell.api.action.lifecycle.Service;
Hyunsun Moonc7219222017-03-27 11:05:59 +090021import org.onosproject.cli.AbstractShellCommand;
22import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
Hyunsun Moonc7219222017-03-27 11:05:59 +090023import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
Hyunsun Moonae51e732017-04-25 17:46:21 +090024import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupAdminService;
Jian Li51b844c2018-05-31 10:59:03 +090025import org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil;
Jian Li39057872018-04-16 11:33:12 +090026import org.onosproject.openstacknode.api.OpenstackNode;
27import org.onosproject.openstacknode.api.OpenstackNodeService;
Hyunsun Moonc7219222017-03-27 11:05:59 +090028import org.openstack4j.api.OSClient;
Hyunsun Moonc7219222017-03-27 11:05:59 +090029import org.openstack4j.model.network.IP;
30import org.openstack4j.model.network.NetFloatingIP;
31import org.openstack4j.model.network.Network;
32import org.openstack4j.model.network.Port;
33import org.openstack4j.model.network.Router;
Hyunsun Moonc7219222017-03-27 11:05:59 +090034import org.openstack4j.model.network.Subnet;
Hyunsun Moonc7219222017-03-27 11:05:59 +090035
sanghoshin2a354e32018-11-09 12:52:44 +080036import java.util.HashMap;
Hyunsun Moonc7219222017-03-27 11:05:59 +090037import java.util.List;
sanghoshin2a354e32018-11-09 12:52:44 +080038import java.util.Map;
Hyunsun Moonc7219222017-03-27 11:05:59 +090039import java.util.Objects;
Jian Li39057872018-04-16 11:33:12 +090040import java.util.Optional;
Hyunsun Moonc7219222017-03-27 11:05:59 +090041import java.util.stream.Collectors;
42
Jian Li0b564282018-06-20 00:50:53 +090043import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.addRouterIface;
Jian Li39057872018-04-16 11:33:12 +090044import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
Hyunsun Moonc7219222017-03-27 11:05:59 +090045
46/**
47 * Synchronizes OpenStack network states.
48 */
Ray Milkey7a2dee52018-09-28 10:58:28 -070049@Service
Hyunsun Moonc7219222017-03-27 11:05:59 +090050@Command(scope = "onos", name = "openstack-sync-states",
51 description = "Synchronizes all OpenStack network states")
52public class OpenstackSyncStateCommand extends AbstractShellCommand {
53
Hyunsun Moonae51e732017-04-25 17:46:21 +090054 private static final String SECURITY_GROUP_FORMAT = "%-40s%-20s";
Hyunsun Moonc7219222017-03-27 11:05:59 +090055 private static final String NETWORK_FORMAT = "%-40s%-20s%-20s%-8s";
56 private static final String SUBNET_FORMAT = "%-40s%-20s%-20s";
57 private static final String PORT_FORMAT = "%-40s%-20s%-20s%-8s";
58 private static final String ROUTER_FORMAT = "%-40s%-20s%-20s%-8s";
59 private static final String FLOATING_IP_FORMAT = "%-40s%-20s%-20s";
60
61 private static final String DEVICE_OWNER_GW = "network:router_gateway";
62 private static final String DEVICE_OWNER_IFACE = "network:router_interface";
63
sanghoshin2a354e32018-11-09 12:52:44 +080064 private static final String HTTP_HEADER_ACCEPT = "accept";
65 private static final String HTTP_HEADER_VALUE_JSON = "application/json";
66
Hyunsun Moonc7219222017-03-27 11:05:59 +090067 @Override
Ray Milkey86ad7bb2018-09-27 12:32:28 -070068 protected void doExecute() {
Jian Li5ecfd1a2018-12-10 11:41:03 +090069 OpenstackSecurityGroupAdminService osSgAdminService =
70 get(OpenstackSecurityGroupAdminService.class);
71 OpenstackNetworkAdminService osNetAdminService =
72 get(OpenstackNetworkAdminService.class);
73 OpenstackRouterAdminService osRouterAdminService =
74 get(OpenstackRouterAdminService.class);
Jian Li39057872018-04-16 11:33:12 +090075 OpenstackNodeService osNodeService = get(OpenstackNodeService.class);
76
Jian Li5ecfd1a2018-12-10 11:41:03 +090077 Map<String, String> headerMap = new HashMap<>();
sanghoshin2a354e32018-11-09 12:52:44 +080078 headerMap.put(HTTP_HEADER_ACCEPT, HTTP_HEADER_VALUE_JSON);
79
Jian Li39057872018-04-16 11:33:12 +090080 Optional<OpenstackNode> node = osNodeService.nodes(CONTROLLER).stream().findFirst();
81 if (!node.isPresent()) {
82 error("Keystone auth info has not been configured. " +
83 "Please specify auth info via network-cfg.json.");
84 return;
85 }
86
Jian Li51b844c2018-05-31 10:59:03 +090087 OSClient osClient = OpenstackNetworkingUtil.getConnectedClient(node.get());
Jian Li39057872018-04-16 11:33:12 +090088
Jian Li51b844c2018-05-31 10:59:03 +090089 if (osClient == null) {
Hyunsun Moonc7219222017-03-27 11:05:59 +090090 return;
Hyunsun Moonc7219222017-03-27 11:05:59 +090091 }
92
Hyunsun Moonae51e732017-04-25 17:46:21 +090093 print("Synchronizing OpenStack security groups");
94 print(SECURITY_GROUP_FORMAT, "ID", "Name");
sanghoshin2a354e32018-11-09 12:52:44 +080095 osClient.headers(headerMap).networking().securitygroup().list().forEach(osSg -> {
Jian Li21536592018-03-06 15:10:55 +090096 if (osSgAdminService.securityGroup(osSg.getId()) != null) {
Hyunsun Moonae51e732017-04-25 17:46:21 +090097 osSgAdminService.updateSecurityGroup(osSg);
98 } else {
99 osSgAdminService.createSecurityGroup(osSg);
100 }
101 print(SECURITY_GROUP_FORMAT, osSg.getId(), osSg.getName());
102 });
103
sanghoshin2a354e32018-11-09 12:52:44 +0800104
Hyunsun Moonae51e732017-04-25 17:46:21 +0900105 print("\nSynchronizing OpenStack networks");
Hyunsun Moonc7219222017-03-27 11:05:59 +0900106 print(NETWORK_FORMAT, "ID", "Name", "VNI", "Subnets");
sanghoshin2a354e32018-11-09 12:52:44 +0800107 osClient.headers(headerMap).networking().network().list().forEach(osNet -> {
Jian Li5a15fe62018-03-06 13:41:20 +0900108 if (osNetAdminService.network(osNet.getId()) != null) {
Hyunsun Moonc7219222017-03-27 11:05:59 +0900109 osNetAdminService.updateNetwork(osNet);
110 } else {
111 osNetAdminService.createNetwork(osNet);
112 }
113 printNetwork(osNet);
114 });
115
sanghoshin2a354e32018-11-09 12:52:44 +0800116
Hyunsun Moonae51e732017-04-25 17:46:21 +0900117 print("\nSynchronizing OpenStack subnets");
Hyunsun Moonc7219222017-03-27 11:05:59 +0900118 print(SUBNET_FORMAT, "ID", "Network", "CIDR");
sanghoshin2a354e32018-11-09 12:52:44 +0800119 osClient.headers(headerMap).networking().subnet().list().forEach(osSubnet -> {
Jian Li5a15fe62018-03-06 13:41:20 +0900120 if (osNetAdminService.subnet(osSubnet.getId()) != null) {
Hyunsun Moonc7219222017-03-27 11:05:59 +0900121 osNetAdminService.updateSubnet(osSubnet);
122 } else {
123 osNetAdminService.createSubnet(osSubnet);
124 }
Jian Li5a15fe62018-03-06 13:41:20 +0900125 printSubnet(osSubnet, osNetAdminService);
Hyunsun Moonc7219222017-03-27 11:05:59 +0900126 });
127
Hyunsun Moonae51e732017-04-25 17:46:21 +0900128 print("\nSynchronizing OpenStack ports");
Hyunsun Moonc7219222017-03-27 11:05:59 +0900129 print(PORT_FORMAT, "ID", "Network", "MAC", "Fixed IPs");
sanghoshin2a354e32018-11-09 12:52:44 +0800130 osClient.headers(headerMap).networking().port().list().forEach(osPort -> {
Jian Li5a15fe62018-03-06 13:41:20 +0900131 if (osNetAdminService.port(osPort.getId()) != null) {
Hyunsun Moonc7219222017-03-27 11:05:59 +0900132 osNetAdminService.updatePort(osPort);
133 } else {
134 osNetAdminService.createPort(osPort);
135 }
Jian Li5a15fe62018-03-06 13:41:20 +0900136 printPort(osPort, osNetAdminService);
Hyunsun Moonc7219222017-03-27 11:05:59 +0900137 });
138
Hyunsun Moonae51e732017-04-25 17:46:21 +0900139 print("\nSynchronizing OpenStack routers");
Hyunsun Moonc7219222017-03-27 11:05:59 +0900140 print(ROUTER_FORMAT, "ID", "Name", "External", "Internal");
sanghoshin2a354e32018-11-09 12:52:44 +0800141 osClient.headers(headerMap).networking().router().list().forEach(osRouter -> {
Jian Lida7c6cb2018-03-06 14:58:54 +0900142 if (osRouterAdminService.router(osRouter.getId()) != null) {
Hyunsun Moonc7219222017-03-27 11:05:59 +0900143 osRouterAdminService.updateRouter(osRouter);
144 } else {
145 osRouterAdminService.createRouter(osRouter);
146 }
147
148 // FIXME do we need to manage router interfaces separately?
Jian Li5a15fe62018-03-06 13:41:20 +0900149 osNetAdminService.ports().stream()
Hyunsun Moonc7219222017-03-27 11:05:59 +0900150 .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
151 Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_IFACE))
Jian Lida7c6cb2018-03-06 14:58:54 +0900152 .forEach(osPort -> addRouterIface(osPort, osRouterAdminService));
Hyunsun Moonc7219222017-03-27 11:05:59 +0900153
Jian Li5a15fe62018-03-06 13:41:20 +0900154 printRouter(osRouter, osNetAdminService);
Hyunsun Moonc7219222017-03-27 11:05:59 +0900155 });
156
Hyunsun Moonae51e732017-04-25 17:46:21 +0900157 print("\nSynchronizing OpenStack floating IPs");
Hyunsun Moonc7219222017-03-27 11:05:59 +0900158 print(FLOATING_IP_FORMAT, "ID", "Floating IP", "Fixed IP");
sanghoshin2a354e32018-11-09 12:52:44 +0800159 osClient.headers(headerMap).networking().floatingip().list().forEach(osFloating -> {
Jian Lida7c6cb2018-03-06 14:58:54 +0900160 if (osRouterAdminService.floatingIp(osFloating.getId()) != null) {
Hyunsun Moonc7219222017-03-27 11:05:59 +0900161 osRouterAdminService.updateFloatingIp(osFloating);
162 } else {
163 osRouterAdminService.createFloatingIp(osFloating);
164 }
165 printFloatingIp(osFloating);
166 });
167 }
168
Hyunsun Moonc7219222017-03-27 11:05:59 +0900169 private void printNetwork(Network osNet) {
170 final String strNet = String.format(NETWORK_FORMAT,
171 osNet.getId(),
172 osNet.getName(),
173 osNet.getProviderSegID(),
174 osNet.getSubnets());
175 print(strNet);
176 }
177
Jian Li5a15fe62018-03-06 13:41:20 +0900178 private void printSubnet(Subnet osSubnet, OpenstackNetworkAdminService osNetService) {
Hyunsun Moonc7219222017-03-27 11:05:59 +0900179 final String strSubnet = String.format(SUBNET_FORMAT,
180 osSubnet.getId(),
181 osNetService.network(osSubnet.getNetworkId()).getName(),
182 osSubnet.getCidr());
183 print(strSubnet);
184 }
185
Jian Li5a15fe62018-03-06 13:41:20 +0900186 private void printPort(Port osPort, OpenstackNetworkAdminService osNetService) {
Hyunsun Moonc7219222017-03-27 11:05:59 +0900187 List<String> fixedIps = osPort.getFixedIps().stream()
188 .map(IP::getIpAddress)
189 .collect(Collectors.toList());
190 final String strPort = String.format(PORT_FORMAT,
191 osPort.getId(),
192 osNetService.network(osPort.getNetworkId()).getName(),
193 osPort.getMacAddress(),
194 fixedIps.isEmpty() ? "" : fixedIps);
195 print(strPort);
196 }
197
Jian Li5a15fe62018-03-06 13:41:20 +0900198 private void printRouter(Router osRouter, OpenstackNetworkAdminService osNetService) {
Hyunsun Moonc7219222017-03-27 11:05:59 +0900199 List<String> externals = osNetService.ports().stream()
200 .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
201 Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_GW))
202 .flatMap(osPort -> osPort.getFixedIps().stream())
203 .map(IP::getIpAddress)
204 .collect(Collectors.toList());
205
206 List<String> internals = osNetService.ports().stream()
207 .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
208 Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_IFACE))
209 .flatMap(osPort -> osPort.getFixedIps().stream())
210 .map(IP::getIpAddress)
211 .collect(Collectors.toList());
212
213 final String strRouter = String.format(ROUTER_FORMAT,
214 osRouter.getId(),
215 osRouter.getName(),
216 externals.isEmpty() ? "" : externals,
217 internals.isEmpty() ? "" : internals);
218 print(strRouter);
219 }
220
221 private void printFloatingIp(NetFloatingIP floatingIp) {
222 final String strFloating = String.format(FLOATING_IP_FORMAT,
223 floatingIp.getId(),
daniel parkeeb8e042018-02-21 14:06:58 +0900224 floatingIp.getFloatingIpAddress(),
Hyunsun Moonc7219222017-03-27 11:05:59 +0900225 Strings.isNullOrEmpty(floatingIp.getFixedIpAddress()) ?
226 "" : floatingIp.getFixedIpAddress());
227 print(strFloating);
228 }
Hyunsun Moonc7219222017-03-27 11:05:59 +0900229}