blob: d07591e6daff4ca75098ceaae020fcef5cd178d3 [file] [log] [blame]
Hyunsun Moonc7219222017-03-27 11:05:59 +09001/*
2 * Copyright 2017-present Open Networking Laboratory
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.openstacknetworking.cli;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import com.google.common.base.Strings;
20import org.apache.karaf.shell.commands.Argument;
21import org.apache.karaf.shell.commands.Command;
22import org.onosproject.cli.AbstractShellCommand;
23import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
24import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
25import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
26import org.onosproject.openstacknetworking.api.OpenstackRouterService;
27import org.openstack4j.api.OSClient;
28import org.openstack4j.api.exceptions.AuthenticationException;
29import org.openstack4j.model.identity.Access;
30import org.openstack4j.model.network.IP;
31import org.openstack4j.model.network.NetFloatingIP;
32import org.openstack4j.model.network.Network;
33import org.openstack4j.model.network.Port;
34import org.openstack4j.model.network.Router;
35import org.openstack4j.model.network.RouterInterface;
36import org.openstack4j.model.network.Subnet;
37import org.openstack4j.openstack.OSFactory;
38import org.openstack4j.openstack.networking.domain.NeutronRouterInterface;
39
40import java.io.IOException;
41import java.util.List;
42import java.util.Objects;
43import java.util.stream.Collectors;
44
45import static org.openstack4j.core.transport.ObjectMapperSingleton.getContext;
46
47/**
48 * Synchronizes OpenStack network states.
49 */
50@Command(scope = "onos", name = "openstack-sync-states",
51 description = "Synchronizes all OpenStack network states")
52public class OpenstackSyncStateCommand extends AbstractShellCommand {
53
54 @Argument(index = 0, name = "endpoint", description = "OpenStack service endpoint",
55 required = true, multiValued = false)
56 private String endpoint = null;
57
58 @Argument(index = 1, name = "tenant", description = "OpenStack admin tenant name",
59 required = true, multiValued = false)
60 private String tenant = null;
61
62 @Argument(index = 2, name = "user", description = "OpenStack admin user name",
63 required = true, multiValued = false)
64 private String user = null;
65
66 @Argument(index = 3, name = "password", description = "OpenStack admin user password",
67 required = true, multiValued = false)
68 private String password = null;
69
70 private static final String NETWORK_FORMAT = "%-40s%-20s%-20s%-8s";
71 private static final String SUBNET_FORMAT = "%-40s%-20s%-20s";
72 private static final String PORT_FORMAT = "%-40s%-20s%-20s%-8s";
73 private static final String ROUTER_FORMAT = "%-40s%-20s%-20s%-8s";
74 private static final String FLOATING_IP_FORMAT = "%-40s%-20s%-20s";
75
76 private static final String DEVICE_OWNER_GW = "network:router_gateway";
77 private static final String DEVICE_OWNER_IFACE = "network:router_interface";
78
79 @Override
80 protected void execute() {
81 OpenstackNetworkAdminService osNetAdminService = get(OpenstackNetworkAdminService.class);
82 OpenstackNetworkService osNetService = get(OpenstackNetworkService.class);
83 OpenstackRouterAdminService osRouterAdminService = get(OpenstackRouterAdminService.class);
84 OpenstackRouterService osRouterService = get(OpenstackRouterService.class);
85
86 Access osAccess;
87 try {
88 osAccess = OSFactory.builder()
89 .endpoint(this.endpoint)
90 .tenantName(this.tenant)
91 .credentials(this.user, this.password)
92 .authenticate()
93 .getAccess();
94 } catch (AuthenticationException e) {
95 print("Authentication failed");
96 return;
97 } catch (Exception e) {
98 print("Failed to access OpenStack service");
99 return;
100 }
101
102 OSClient osClient = OSFactory.clientFromAccess(osAccess);
103
104 print("Synchronizing OpenStack networks...");
105 print(NETWORK_FORMAT, "ID", "Name", "VNI", "Subnets");
106 osClient.networking().network().list().forEach(osNet -> {
107 if (osNetService.network(osNet.getId()) != null) {
108 osNetAdminService.updateNetwork(osNet);
109 } else {
110 osNetAdminService.createNetwork(osNet);
111 }
112 printNetwork(osNet);
113 });
114
115 print("\nSynchronizing OpenStack subnets...");
116 print(SUBNET_FORMAT, "ID", "Network", "CIDR");
117 osClient.networking().subnet().list().forEach(osSubnet -> {
118 if (osNetService.subnet(osSubnet.getId()) != null) {
119 osNetAdminService.updateSubnet(osSubnet);
120 } else {
121 osNetAdminService.createSubnet(osSubnet);
122 }
123 printSubnet(osSubnet, osNetService);
124 });
125
126 print("\nSynchronizing OpenStack ports...");
127 print(PORT_FORMAT, "ID", "Network", "MAC", "Fixed IPs");
128 osClient.networking().port().list().forEach(osPort -> {
129 if (osNetService.port(osPort.getId()) != null) {
130 osNetAdminService.updatePort(osPort);
131 } else {
132 osNetAdminService.createPort(osPort);
133 }
134 printPort(osPort, osNetService);
135 });
136
137 print("\nSynchronizing OpenStack routers...");
138 print(ROUTER_FORMAT, "ID", "Name", "External", "Internal");
139 osClient.networking().router().list().forEach(osRouter -> {
140 if (osRouterService.router(osRouter.getId()) != null) {
141 osRouterAdminService.updateRouter(osRouter);
142 } else {
143 osRouterAdminService.createRouter(osRouter);
144 }
145
146 // FIXME do we need to manage router interfaces separately?
147 osNetService.ports().stream()
148 .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
149 Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_IFACE))
150 .forEach(osPort -> addRouterIface(osPort, osRouterService,
151 osRouterAdminService));
152
153 printRouter(osRouter, osNetService);
154 });
155
156 print("\nSynchronizing OpenStack floating IPs...");
157 print(FLOATING_IP_FORMAT, "ID", "Floating IP", "Fixed IP");
158 osClient.networking().floatingip().list().forEach(osFloating -> {
159 if (osRouterService.floatingIp(osFloating.getId()) != null) {
160 osRouterAdminService.updateFloatingIp(osFloating);
161 } else {
162 osRouterAdminService.createFloatingIp(osFloating);
163 }
164 printFloatingIp(osFloating);
165 });
166 }
167
168 // TODO fix the logic to add router interface to router
169 private void addRouterIface(Port osPort, OpenstackRouterService service,
170 OpenstackRouterAdminService adminService) {
171 osPort.getFixedIps().forEach(p -> {
172 JsonNode jsonTree = mapper().createObjectNode()
173 .put("id", osPort.getDeviceId())
174 .put("tenant_id", osPort.getTenantId())
175 .put("subnet_id", p.getSubnetId())
176 .put("port_id", osPort.getId());
177 try {
178 RouterInterface rIface = getContext(NeutronRouterInterface.class)
179 .readerFor(NeutronRouterInterface.class)
180 .readValue(jsonTree);
181 if (service.routerInterface(rIface.getPortId()) != null) {
182 adminService.updateRouterInterface(rIface);
183 } else {
184 adminService.addRouterInterface(rIface);
185 }
186 } catch (IOException ignore) {
187 }
188 });
189 }
190
191 private void printNetwork(Network osNet) {
192 final String strNet = String.format(NETWORK_FORMAT,
193 osNet.getId(),
194 osNet.getName(),
195 osNet.getProviderSegID(),
196 osNet.getSubnets());
197 print(strNet);
198 }
199
200 private void printSubnet(Subnet osSubnet, OpenstackNetworkService osNetService) {
201 final String strSubnet = String.format(SUBNET_FORMAT,
202 osSubnet.getId(),
203 osNetService.network(osSubnet.getNetworkId()).getName(),
204 osSubnet.getCidr());
205 print(strSubnet);
206 }
207
208 private void printPort(Port osPort, OpenstackNetworkService osNetService) {
209 List<String> fixedIps = osPort.getFixedIps().stream()
210 .map(IP::getIpAddress)
211 .collect(Collectors.toList());
212 final String strPort = String.format(PORT_FORMAT,
213 osPort.getId(),
214 osNetService.network(osPort.getNetworkId()).getName(),
215 osPort.getMacAddress(),
216 fixedIps.isEmpty() ? "" : fixedIps);
217 print(strPort);
218 }
219
220 private void printRouter(Router osRouter, OpenstackNetworkService osNetService) {
221 List<String> externals = osNetService.ports().stream()
222 .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
223 Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_GW))
224 .flatMap(osPort -> osPort.getFixedIps().stream())
225 .map(IP::getIpAddress)
226 .collect(Collectors.toList());
227
228 List<String> internals = osNetService.ports().stream()
229 .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
230 Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_IFACE))
231 .flatMap(osPort -> osPort.getFixedIps().stream())
232 .map(IP::getIpAddress)
233 .collect(Collectors.toList());
234
235 final String strRouter = String.format(ROUTER_FORMAT,
236 osRouter.getId(),
237 osRouter.getName(),
238 externals.isEmpty() ? "" : externals,
239 internals.isEmpty() ? "" : internals);
240 print(strRouter);
241 }
242
243 private void printFloatingIp(NetFloatingIP floatingIp) {
244 final String strFloating = String.format(FLOATING_IP_FORMAT,
245 floatingIp.getId(),
246 floatingIp.getFixedIpAddress(),
247 Strings.isNullOrEmpty(floatingIp.getFixedIpAddress()) ?
248 "" : floatingIp.getFixedIpAddress());
249 print(strFloating);
250 }
251}