Allow sync state CLI commands to read values from netcfg
Change-Id: If777fba32f9256e96e8bcfe5d28d29ca7d617416
diff --git a/pom.xml b/pom.xml
index 02a6093..4cf2ba8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -204,6 +204,11 @@
<version>2.11</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.console</artifactId>
+ </dependency>
+
</dependencies>
<build>
diff --git a/src/main/java/org/opencord/cordvtn/api/CordVtnConfig.java b/src/main/java/org/opencord/cordvtn/api/CordVtnConfig.java
index 7dea415..fc7f903 100644
--- a/src/main/java/org/opencord/cordvtn/api/CordVtnConfig.java
+++ b/src/main/java/org/opencord/cordvtn/api/CordVtnConfig.java
@@ -79,8 +79,15 @@
@Deprecated
private static final String OPENSTACK = "openstack";
+ private static final String OPENSTACK_ENDPOINT = "endpoint";
+ private static final String OPENSTACK_TENANT = "tenant";
+ private static final String OPENSTACK_USER = "user";
+ private static final String OPENSTACK_PASSWORD = "password";
@Deprecated
private static final String XOS = "xos";
+ private static final String XOS_ENDPOINT = "endpoint";
+ private static final String XOS_USER = "user";
+ private static final String XOS_PASSWORD = "password";
private static final String CONTROLLERS = "controllers";
private static final int INDEX_IP = 0;
@@ -307,4 +314,60 @@
String[] ctrl = jsonNode.asText().split(":");
return Integer.parseInt(ctrl[INDEX_PORT]);
}
+
+ public String getXosEndpoint() {
+ JsonNode xosObject = object.get(XOS);
+ if (xosObject == null) {
+ return null;
+ }
+ return xosObject.get(XOS_ENDPOINT).asText();
+ }
+
+ public String getXosUsername() {
+ JsonNode xosObject = object.get(XOS);
+ if (xosObject == null) {
+ return null;
+ }
+ return xosObject.get(XOS_USER).asText();
+ }
+
+ public String getXosPassword() {
+ JsonNode xosObject = object.get(XOS);
+ if (xosObject == null) {
+ return null;
+ }
+ return xosObject.get(XOS_PASSWORD).asText();
+ }
+
+ public String getOpenstackEndpoint() {
+ JsonNode xosObject = object.get(OPENSTACK);
+ if (xosObject == null) {
+ return null;
+ }
+ return xosObject.get(OPENSTACK_ENDPOINT).asText();
+ }
+
+ public String getOpenstackTenant() {
+ JsonNode xosObject = object.get(OPENSTACK);
+ if (xosObject == null) {
+ return null;
+ }
+ return xosObject.get(OPENSTACK_TENANT).asText();
+ }
+
+ public String getOpenstackUser() {
+ JsonNode xosObject = object.get(OPENSTACK);
+ if (xosObject == null) {
+ return null;
+ }
+ return xosObject.get(OPENSTACK_USER).asText();
+ }
+
+ public String getOpenstackPassword() {
+ JsonNode xosObject = object.get(OPENSTACK);
+ if (xosObject == null) {
+ return null;
+ }
+ return xosObject.get(OPENSTACK_PASSWORD).asText();
+ }
}
diff --git a/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkAdminService.java b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkAdminService.java
index d52213f..0563a88 100644
--- a/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkAdminService.java
+++ b/src/main/java/org/opencord/cordvtn/api/core/ServiceNetworkAdminService.java
@@ -31,6 +31,39 @@
void purgeStates();
/**
+ * Request state synchronization from XOS. The XOS connection parameters
+ * will be pulled from the netcfg.
+ */
+ void syncXosState();
+
+ /**
+ * Request state synchronization from XOS using the given XOS connection
+ * parameters.
+ *
+ * @param endpoint XOS REST endpoint
+ * @param user XOS username
+ * @param password XOS password
+ */
+ void syncXosState(String endpoint, String user, String password);
+
+ /**
+ * Synchronize state with Neutron. The Neutron connection parameters will be
+ * pulled from the netcfg.
+ */
+ void syncNeutronState();
+
+ /**
+ * Synchronize state with Neutron using the given Neutron connection
+ * parameters.
+ *
+ * @param endpoint Neutron REST endpoint
+ * @param tenant Neutron tenant
+ * @param user Neutron username
+ * @param password Neutron password
+ */
+ void syncNeutronState(String endpoint, String tenant, String user, String password);
+
+ /**
* Creates a service network with the given information.
*
* @param serviceNetwork the new service network
diff --git a/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncNeutronStatesCommand.java b/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncNeutronStatesCommand.java
index 85cda91..5fdf522 100644
--- a/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncNeutronStatesCommand.java
+++ b/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncNeutronStatesCommand.java
@@ -17,25 +17,9 @@
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
+import org.apache.karaf.shell.commands.Option;
import org.onosproject.cli.AbstractShellCommand;
import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
-import org.opencord.cordvtn.api.net.NetworkId;
-import org.opencord.cordvtn.api.net.PortId;
-import org.opencord.cordvtn.api.net.SegmentId;
-import org.opencord.cordvtn.api.net.ServiceNetwork;
-import org.opencord.cordvtn.api.net.ServicePort;
-import org.opencord.cordvtn.impl.DefaultServiceNetwork;
-import org.opencord.cordvtn.impl.DefaultServicePort;
-import org.openstack4j.api.OSClient;
-import org.openstack4j.api.exceptions.AuthenticationException;
-import org.openstack4j.model.identity.Access;
-import org.openstack4j.openstack.OSFactory;
-
-import java.util.List;
-import java.util.stream.Collectors;
/**
* Synchronizes network states with OpenStack Neutron.
@@ -46,6 +30,10 @@
description = "Synchronizes network states with Neutron")
public class CordVtnSyncNeutronStatesCommand extends AbstractShellCommand {
+ @Option(name = "-c", aliases = "--config", description = "Use connection values from config",
+ required = false, multiValued = false)
+ private boolean config = false;
+
@Argument(index = 0, name = "endpoint", description = "OpenStack service endpoint",
required = true, multiValued = false)
private String endpoint = null;
@@ -62,101 +50,16 @@
required = true, multiValued = false)
private String password = null;
- private static final String PORT_NAME_PREFIX = "tap";
- private static final String NET_FORMAT = "%-40s%-30s%-20s%-8s%-20s%s";
- private static final String PORT_FORMAT = "%-40s%-30s%-20s%-18s%-10s%s";
-
@Override
protected void execute() {
ServiceNetworkAdminService snetService =
AbstractShellCommand.get(ServiceNetworkAdminService.class);
- Access osAccess;
- try {
- osAccess = OSFactory.builder()
- .endpoint(this.endpoint)
- .tenantName(this.tenant)
- .credentials(this.user, this.password)
- .authenticate()
- .getAccess();
- } catch (AuthenticationException e) {
- print("Authentication failed");
- return;
- } catch (Exception e) {
- print("OpenStack service endpoint is unreachable");
- return;
+
+ print("Synchronizing neutron state...");
+ if (config) {
+ snetService.syncNeutronState();
+ } else {
+ snetService.syncNeutronState(endpoint, tenant, user, password);
}
-
- print("Synchronizing service networks...");
- print(NET_FORMAT, "ID", "Name", "Type", "VNI", "Subnet", "Service IP");
- OSClient osClient = OSFactory.clientFromAccess(osAccess);
- osClient.networking().network().list().forEach(osNet -> {
- ServiceNetwork snet = DefaultServiceNetwork.builder()
- .id(NetworkId.of(osNet.getId()))
- .name(osNet.getName())
- .type(ServiceNetwork.NetworkType.PRIVATE)
- .segmentId(SegmentId.of(Long.valueOf(osNet.getProviderSegID())))
- .build();
- try {
- if (snetService.serviceNetwork(snet.id()) != null) {
- snetService.updateServiceNetwork(snet);
- } else {
- snetService.createServiceNetwork(snet);
- }
- } catch (Exception ignore) {
- }
- });
-
- osClient.networking().subnet().list().forEach(osSubnet -> {
- try {
- ServiceNetwork snet = DefaultServiceNetwork.builder()
- .id(NetworkId.of(osSubnet.getNetworkId()))
- .subnet(IpPrefix.valueOf(osSubnet.getCidr()))
- .serviceIp(IpAddress.valueOf(osSubnet.getGateway()))
- .build();
- snetService.updateServiceNetwork(snet);
- ServiceNetwork updated = snetService.serviceNetwork(snet.id());
- print(NET_FORMAT, updated.id(),
- updated.name(),
- updated.type(),
- updated.segmentId(),
- updated.subnet(),
- updated.serviceIp());
- } catch (Exception e) {
- print(e.getMessage());
- }
- });
-
- print("\nSynchronizing service ports...");
- print(PORT_FORMAT, "ID", "Name", "MAC", "IP", "VLAN", "WAN IPs");
- osClient.networking().port().list().forEach(osPort -> {
- ServicePort.Builder sportBuilder = DefaultServicePort.builder()
- .id(PortId.of(osPort.getId()))
- .name(PORT_NAME_PREFIX + osPort.getId().substring(0, 11))
- .networkId(NetworkId.of(osPort.getNetworkId()));
-
- if (osPort.getMacAddress() != null) {
- sportBuilder.mac(MacAddress.valueOf(osPort.getMacAddress()));
- }
- if (!osPort.getFixedIps().isEmpty()) {
- sportBuilder.ip(IpAddress.valueOf(
- osPort.getFixedIps().iterator().next().getIpAddress()));
- }
- ServicePort sport = sportBuilder.build();
- if (snetService.servicePort(sport.id()) != null) {
- snetService.updateServicePort(sport);
- } else {
- snetService.createServicePort(sport);
- }
- ServicePort updated = snetService.servicePort(sport.id());
- List<String> floatingIps = updated.addressPairs().stream()
- .map(ip -> ip.ip().toString())
- .collect(Collectors.toList());
- print(PORT_FORMAT, updated.id(),
- updated.name(),
- updated.mac(),
- updated.ip(),
- updated.vlanId() != null ? updated.vlanId() : "",
- floatingIps.isEmpty() ? "" : floatingIps);
- });
}
}
diff --git a/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncXosStatesCommand.java b/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncXosStatesCommand.java
index 687c1a4..4b747b8 100644
--- a/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncXosStatesCommand.java
+++ b/src/main/java/org/opencord/cordvtn/cli/CordVtnSyncXosStatesCommand.java
@@ -17,8 +17,9 @@
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
import org.onosproject.cli.AbstractShellCommand;
-import org.opencord.cordvtn.rest.XosVtnNetworkingClient;
+import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
/**
* Synchronizes network states with XOS VTN service.
@@ -29,6 +30,10 @@
description = "Synchronizes network states with XOS")
public class CordVtnSyncXosStatesCommand extends AbstractShellCommand {
+ @Option(name = "-c", aliases = "--config", description = "Use connection values from config",
+ required = false, multiValued = false)
+ private boolean config = false;
+
@Argument(index = 0, name = "endpoint", description = "XOS VTN service endpoint",
required = true, multiValued = false)
private String endpoint = null;
@@ -43,13 +48,12 @@
@Override
protected void execute() {
- XosVtnNetworkingClient client = XosVtnNetworkingClient.builder()
- .endpoint(endpoint)
- .user(user)
- .password(password)
- .build();
-
print("Requesting state synchronization");
- client.requestSync();
+ ServiceNetworkAdminService snService = get(ServiceNetworkAdminService.class);
+ if (config) {
+ snService.syncXosState();
+ } else {
+ snService.syncXosState(endpoint, user, password);
+ }
}
}
diff --git a/src/main/java/org/opencord/cordvtn/impl/ServiceNetworkManager.java b/src/main/java/org/opencord/cordvtn/impl/ServiceNetworkManager.java
index 3bb305d..69b6fcb 100644
--- a/src/main/java/org/opencord/cordvtn/impl/ServiceNetworkManager.java
+++ b/src/main/java/org/opencord/cordvtn/impl/ServiceNetworkManager.java
@@ -23,6 +23,9 @@
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.event.ListenerRegistry;
@@ -42,9 +45,15 @@
import org.opencord.cordvtn.api.core.ServiceNetworkStoreDelegate;
import org.opencord.cordvtn.api.net.NetworkId;
import org.opencord.cordvtn.api.net.PortId;
+import org.opencord.cordvtn.api.net.SegmentId;
import org.opencord.cordvtn.api.net.ServiceNetwork;
import org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType;
import org.opencord.cordvtn.api.net.ServicePort;
+import org.opencord.cordvtn.rest.XosVtnNetworkingClient;
+import org.openstack4j.api.OSClient;
+import org.openstack4j.api.exceptions.AuthenticationException;
+import org.openstack4j.model.identity.Access;
+import org.openstack4j.openstack.OSFactory;
import org.slf4j.Logger;
import java.util.Map;
@@ -95,6 +104,8 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ServiceNetworkStore snetStore;
+ private ApplicationId appId;
+
// TODO add cordvtn config service and move this
private static final Class<CordVtnConfig> CONFIG_CLASS = CordVtnConfig.class;
private final ConfigFactory configFactory =
@@ -110,7 +121,7 @@
@Activate
protected void activate() {
- coreService.registerApplication(Constants.CORDVTN_APP_ID);
+ appId = coreService.registerApplication(Constants.CORDVTN_APP_ID);
configRegistry.registerConfigFactory(configFactory);
snetStore.setDelegate(delegate);
log.info("Started");
@@ -129,6 +140,104 @@
}
@Override
+ public void syncXosState() {
+ CordVtnConfig config = configRegistry.getConfig(appId, CONFIG_CLASS);
+ if (config == null) {
+ return;
+ }
+ syncXosState(config.getXosEndpoint(), config.getXosUsername(), config.getXosPassword());
+ }
+
+ @Override
+ public void syncXosState(String endpoint, String user, String password) {
+ checkNotNull(endpoint);
+ checkNotNull(user);
+ checkNotNull(password);
+
+ XosVtnNetworkingClient client = XosVtnNetworkingClient.builder()
+ .endpoint(endpoint)
+ .user(user)
+ .password(password)
+ .build();
+
+ client.requestSync();
+ }
+
+ @Override
+ public void syncNeutronState() {
+ CordVtnConfig config = configRegistry.getConfig(appId, CONFIG_CLASS);
+ if (config == null) {
+ return;
+ }
+ syncNeutronState(config.getOpenstackEndpoint(), config.getOpenstackTenant(),
+ config.getOpenstackUser(), config.getOpenstackPassword());
+ }
+
+ @Override
+ public void syncNeutronState(String endpoint, String tenant, String user, String password) {
+ Access osAccess;
+ try {
+ osAccess = OSFactory.builder()
+ .endpoint(endpoint)
+ .tenantName(tenant)
+ .credentials(user, password)
+ .authenticate()
+ .getAccess();
+ } catch (AuthenticationException e) {
+ log.warn("Authentication failed");
+ return;
+ } catch (Exception e) {
+ log.warn("OpenStack service endpoint is unreachable");
+ return;
+ }
+
+ OSClient osClient = OSFactory.clientFromAccess(osAccess);
+ osClient.networking().network().list().forEach(osNet -> {
+ ServiceNetwork snet = DefaultServiceNetwork.builder()
+ .id(NetworkId.of(osNet.getId()))
+ .name(osNet.getName())
+ .type(ServiceNetwork.NetworkType.PRIVATE)
+ .segmentId(SegmentId.of(Long.valueOf(osNet.getProviderSegID())))
+ .build();
+ if (serviceNetwork(snet.id()) != null) {
+ updateServiceNetwork(snet);
+ } else {
+ createServiceNetwork(snet);
+ }
+ });
+
+ osClient.networking().subnet().list().forEach(osSubnet -> {
+ ServiceNetwork snet = DefaultServiceNetwork.builder()
+ .id(NetworkId.of(osSubnet.getNetworkId()))
+ .subnet(IpPrefix.valueOf(osSubnet.getCidr()))
+ .serviceIp(IpAddress.valueOf(osSubnet.getGateway()))
+ .build();
+ updateServiceNetwork(snet);
+ });
+
+ osClient.networking().port().list().forEach(osPort -> {
+ ServicePort.Builder sportBuilder = DefaultServicePort.builder()
+ .id(PortId.of(osPort.getId()))
+ .name("tap" + osPort.getId().substring(0, 11))
+ .networkId(NetworkId.of(osPort.getNetworkId()));
+
+ if (osPort.getMacAddress() != null) {
+ sportBuilder.mac(MacAddress.valueOf(osPort.getMacAddress()));
+ }
+ if (!osPort.getFixedIps().isEmpty()) {
+ sportBuilder.ip(IpAddress.valueOf(
+ osPort.getFixedIps().iterator().next().getIpAddress()));
+ }
+ ServicePort sport = sportBuilder.build();
+ if (servicePort(sport.id()) != null) {
+ updateServicePort(sport);
+ } else {
+ createServicePort(sport);
+ }
+ });
+ }
+
+ @Override
public ServiceNetwork serviceNetwork(NetworkId netId) {
checkNotNull(netId, ERR_NULL_SERVICE_NET_ID);
return snetStore.serviceNetwork(netId);