[ONOS-7731] Update api interface & implementation of openstack vtap app

Change-Id: I7c3c7888b00a7357b13e3b1756e9cd0a1bb6a5c0
This commit is contained in:
Jimo Jung 2018-09-03 16:28:13 +09:00 committed by Jian Li
parent b8cdcc156c
commit 14e87bf5e8
52 changed files with 3635 additions and 1310 deletions

View File

@ -4,12 +4,12 @@ BUNDLES = [
]
onos_app (
title = 'OpenStack vTap Application',
title = 'Openstack Vtap Application',
category = 'Integration',
url = 'https://wiki.onosproject.org/display/ONOS/SONA%3A+DC+Network+Virtualization',
included_bundles = BUNDLES,
description = 'SONA Openstack vTap Application.',
description = 'SONA Openstack Vtap Application.',
required_apps = [
'org.onosproject.openstacknetworking'
'org.onosproject.openstacknetworking',
]
)

View File

@ -4,12 +4,13 @@ BUNDLES = [
]
onos_app(
app_name = "org.onosproject.openstackvtap",
category = "Integration",
description = "SONA Openstack vTap Application.",
description = "Openstack Vtap Application.",
included_bundles = BUNDLES,
required_apps = [
"org.onosproject.openstacknetworking",
],
title = "OpenStack vTap Application",
title = "Openstack Vtap Application",
url = "https://wiki.onosproject.org/display/ONOS/SONA%3A+DC+Network+Virtualization",
)

View File

@ -22,15 +22,14 @@ import org.onosproject.net.SparseAnnotations;
import java.util.Set;
/**
* Abstraction of an OpenstackVtap.
* Abstraction of an openstack vtap.
*/
public interface OpenstackVtap extends Annotated {
/**
* Openstack vTap type.
* List of openstack vtap types.
*/
enum Type {
/**
* Indicates mirroring both TX and RX traffic.
*/
@ -47,9 +46,9 @@ public interface OpenstackVtap extends Annotated {
VTAP_TX(0x1),
/**
* Indicates do not mirroring any traffic.
* Indicates selection of mirroring any traffic.
*/
VTAP_NONE(0);
VTAP_ANY(0x0);
private final int type;
@ -63,97 +62,96 @@ public interface OpenstackVtap extends Annotated {
}
/**
* OpenstackVtap identifier.
* Returns the openstack vtap identifier.
*
* @return OpenstackVtap id
* @return vtap ID
*/
OpenstackVtapId id();
/**
* Returns OpenstackVtap type.
* Returns the openstack vtap type.
*
* @return type
* @return type of vtap
*/
Type type();
/**
* Returns the vTap criterion.
* Returns the openstack vtap criterion.
*
* @return vTap criterion
* @return criterion of vtap
*/
OpenstackVtapCriterion vTapCriterion();
OpenstackVtapCriterion vtapCriterion();
/**
* Returns a collection of TX device identifiers.
* Returns a collection of device identifiers for tx.
*
* @return device identifiers
* @return device identifiers for tx
*/
Set<DeviceId> txDeviceIds();
/**
* Returns a collection of RX device identifiers.
* Returns a collection of device identifiers for rx.
*
* @return device identifiers
* @return device identifiers for rx
*/
Set<DeviceId> rxDeviceIds();
/**
* Builder of new openstack vTap instance.
* Builder of new openstack vtap instance.
*/
interface Builder {
/**
* Returns openstack vTap builder with supplied vTap identifier.
* Returns openstack vtap builder with supplied id.
*
* @param id vTap identifier
* @return openstack vTap builder
* @param id openstack vtap id
* @return openstack vtap builder
*/
Builder id(OpenstackVtapId id);
/**
* Returns openstack vTap builder with supplied vTap type.
* Returns openstack vtap builder with supplied type.
*
* @param type vTap type
* @return openstack vTap builder
* @param type of the vtap
* @return openstack vtap builder
*/
Builder type(OpenstackVtap.Type type);
/**
* Returns openstack vTap builder with supplied vTap criterion.
* Returns openstack vtap builder with supplied criterion.
*
* @param vTapCriterion vTap criterion
* @return openstack vTap builder
* @param vtapCriterion for the vtap
* @return openstack vtap builder
*/
Builder vTapCriterion(OpenstackVtapCriterion vTapCriterion);
Builder vtapCriterion(OpenstackVtapCriterion vtapCriterion);
/**
* Returns openstack vTap builder with supplied TX device identifiers.
* Returns openstack vtap builder with supplied tx deviceId set.
*
* @param txDeviceIds TX device identifiers
* @return openstack vTap builder
* @param txDeviceIds deviceId set for tx
* @return openstack vtap builder
*/
Builder txDeviceIds(Set<DeviceId> txDeviceIds);
/**
* Returns openstack vTap builder with supplied RX device identifiers.
* Returns openstack vtap builder with supplied rx deviceId set.
*
* @param rxDeviceIds RX device identifiers
* @return openstack vTap builder
* @param rxDeviceIds deviceId set for rx
* @return openstack vtap builder
*/
Builder rxDeviceIds(Set<DeviceId> rxDeviceIds);
/**
* Returns openstack vTap builder with supplied annotations.
* Returns openstack vtap builder with supplied annotations.
*
* @param annotations a set of annotations
* @return openstack vTap builder
* @return openstack vtap builder
*/
Builder annotations(SparseAnnotations... annotations);
Builder annotations(SparseAnnotations annotations);
/**
* Builds an immutable openstack vTap instance.
* Builds an immutable OpenstackVtap instance.
*
* @return openstack vTap instance
* @return openstack vtap instance
*/
OpenstackVtap build();
}

View File

@ -15,60 +15,24 @@
*/
package org.onosproject.openstackvtap.api;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
/**
* Service for administering the inventory of vTap.
* Service for administering the inventory of openstack vtap.
*/
public interface OpenstackVtapAdminService extends OpenstackVtapService {
/**
* Creates a new vTap based on the specified description.
*
* @param type vTap type
* @param vTapCriterion criterion of a vTap
* @return created vTap object or null if error occurred
* Initializes the flow rules and group tables, tunneling interface for all completed compute nodes.
*/
OpenstackVtap createVtap(OpenstackVtap.Type type, OpenstackVtapCriterion vTapCriterion);
void initVtap();
/**
* Updates the existing vTap based on the given vTap instance.
*
* @param vTapId vTap identifier
* @param vTap vTap instance to be modified
* @return updated vTap object or null if error occurred
* Clears the flow rules and group tables, tunneling interfaces for all compute nodes.
*/
OpenstackVtap updateVtap(OpenstackVtapId vTapId, OpenstackVtap vTap);
void clearVtap();
/**
* Removes the specified vTap with given vTap identifier.
*
* @param vTapId vTap identifier
* @return removed vTap object or null if error occurred
* Purges all flow rules and group tables, tunneling interface for openstack vtap.
*/
OpenstackVtap removeVtap(OpenstackVtapId vTapId);
void purgeVtap();
/**
* Sets output port and VLAN tag for vTap.
*
* @param deviceId device identifier
* @param type vTap type
* @param portNumber port number
* @param vlanId VLAN tag
*/
void setVtapOutput(DeviceId deviceId, OpenstackVtap.Type type,
PortNumber portNumber, VlanId vlanId);
/**
* Sets output port and VNI for vTap.
*
* @param deviceId device identifier
* @param type vTap type
* @param portNumber port number
* @param vni virtual network index (VNI) of VxLAN
*/
void setVtapOutput(DeviceId deviceId, OpenstackVtap.Type type,
PortNumber portNumber, int vni);
}

View File

@ -19,35 +19,35 @@ import org.onlab.packet.IpPrefix;
import org.onlab.packet.TpPort;
/**
* A vTAP criterion used for mirroring traffic.
* A vtap criterion used for mirroring traffic.
*/
public interface OpenstackVtapCriterion {
/**
* Returns IP Prefix of Source VM.
* Returns IP prefix of source.
*
* @return source IP prefix
* @return source IP prefix of vtap criterion
*/
IpPrefix srcIpPrefix();
/**
* Returns IP Prefix of Destination VM.
* Returns IP prefix of destination.
*
* @return destination IP prefix
* @return destination IP prefix of vtap criterion
*/
IpPrefix dstIpPrefix();
/**
* Returns IP protocol.
*
* @return IP protocol
* @return IP protocol of vtap criterion
*/
byte ipProtocol();
/**
* Returns source transport port.
*
* @return source transport port number
* @return source transport port of vtap criterion
*/
TpPort srcTpPort();
@ -55,60 +55,59 @@ public interface OpenstackVtapCriterion {
/**
* Returns destination transport port.
*
* @return destination transport port number
* @return destination transport port of vtap criterion
*/
TpPort dstTpPort();
/**
* Builder of new openstack vTap criteria.
* Builder of new OpenstackVtapCriterion instance.
*/
interface Builder {
/**
* Builds an immutable openstack vTap criterion instance.
* Returns openstack vtap criterion builder with supplied source IP prefix.
*
* @return openstack vTap criterion
*/
OpenstackVtapCriterion build();
/**
* Returns openstack vTap criterion builder with supplied srcIpPrefix.
*
* @param srcIpPrefix Source IP address
* @return openstack vTap criterion builder
* @param srcIpPrefix Source IP prefix
* @return openstack vtap criterion builder
*/
Builder srcIpPrefix(IpPrefix srcIpPrefix);
/**
* Returns openstack vTap criterion builder with supplied srcIpPrefix.
* Returns openstack vtap criterion builder with supplied destination IP prefix.
*
* @param dstIpPrefix Destination IP Prefix
* @return openstack vTap criterion builder
* @param dstIpPrefix Destination IP prefix
* @return openstack vtap criterion builder
*/
Builder dstIpPrefix(IpPrefix dstIpPrefix);
/**
* Returns openstack vTap criterion builder with supplied ipProtocol.
* Returns openstack vtap criterion builder with supplied ipProtocol.
*
* @param ipProtocol IP protocol number
* @return openstack vTap criterion builder
* @param ipProtocol IP protocol
* @return openstack vtap criterion builder
*/
Builder ipProtocol(byte ipProtocol);
/**
* Returns openstack vTap criterion builder with supplied srcTpPort.
* Returns openstack vtap criterion builder with supplied source port.
*
* @param srcTpPort Source transport port number
* @return openstack vTap criterion builder
* @param srcTpPort Source transport port
* @return openstack vtap criterion builder
*/
Builder srcTpPort(TpPort srcTpPort);
/**
* Returns openstack vTap criterion builder with supplied dstTpPort.
* Returns openstack vtap criterion builder with supplied destination port.
*
* @param dstTpPort Destination transport port number
* @return openstack vTap criterion builder
* @param dstTpPort Destination transport port
* @return openstack vtap criterion builder
*/
Builder dstTpPort(TpPort dstTpPort);
/**
* Builds an immutable OpenstackVtapCriterion instance.
*
* @return OpenstackVtapCriterion criterion
*/
OpenstackVtapCriterion build();
}
}

View File

@ -19,81 +19,166 @@ import org.onlab.util.Tools;
import org.onosproject.event.AbstractEvent;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkState;
/**
* Describes vTap event.
* Describes openstack vtap event.
*/
public class OpenstackVtapEvent extends AbstractEvent<OpenstackVtapEvent.Type, OpenstackVtap> {
public class OpenstackVtapEvent extends AbstractEvent<OpenstackVtapEvent.Type, Object> {
private static final String INVALID_OBJ_TYPE = "Invalid OpenstackVtapEvent object type of %";
/**
* Type of vTap events.
* Type of openstack vtap events.
*/
public enum Type {
/**
* Signifies that a new vTap has been added.
* Signifies that a new openstack vtap network has been added.
*/
VTAP_NETWORK_ADDED,
/**
* Signifies that a openstack vtap network has been changed.
*/
VTAP_NETWORK_UPDATED,
/**
* Signifies that a openstack vtap network has been removed.
*/
VTAP_NETWORK_REMOVED,
/**
* Signifies that a new openstack vtap has been added.
*/
VTAP_ADDED,
/**
* Signifies that a vTap has been removed.
*/
VTAP_REMOVED,
/**
* Signifies that a vTap data changed.
* Signifies that a openstack vtap has been changed.
*/
VTAP_UPDATED,
/**
* Signifies that a openstack vtap has been removed.
*/
VTAP_REMOVED,
}
private OpenstackVtap prevSubject;
private final Object prevSubject;
/**
* Creates an event of a given type and for the specified vTap and the
* current time.
* Creates an event with previous openstack vtap network subject.
*
* @param type vTap event type
* @param vTap event vTap subject
* The openstack vtap network subject is null if the type is removed
* The previous openstack vtap network subject is null if the type is added
*
* @param type openstack vtap event type
* @param vtapNetwork event openstack vtap network subject
* @param prevVtapNetwork previous openstack vtap network subject
*/
public OpenstackVtapEvent(Type type, OpenstackVtap vTap) {
super(type, vTap);
public OpenstackVtapEvent(Type type,
OpenstackVtapNetwork vtapNetwork,
OpenstackVtapNetwork prevVtapNetwork) {
super(type, vtapNetwork);
prevSubject = prevVtapNetwork;
}
/**
* Creates an event of a given type and for the specified vTap and time.
* Creates an event of a given type and for the specified openstack vtap network and time.
*
* @param type vTap event type
* @param vTap event vTap subject
* @param time occurrence time
* @param type openstack vtap event type
* @param vtapNetwork event openstack vtap network subject
* @param prevVtapNetwork previous openstack vtap network subject
* @param time occurrence time
*/
public OpenstackVtapEvent(Type type, OpenstackVtap vTap, long time) {
super(type, vTap, time);
public OpenstackVtapEvent(Type type,
OpenstackVtapNetwork vtapNetwork,
OpenstackVtapNetwork prevVtapNetwork,
long time) {
super(type, vtapNetwork, time);
prevSubject = prevVtapNetwork;
}
/**
* Creates an event with previous subject.
* Creates an event with previous openstack vtap subject.
*
* The previous subject is ignored if the type is not moved or updated
* The openstack vtap subject is null if the type is removed
* The previous openstack vtap subject is null if the type is added
*
* @param type vTap event type
* @param vTap event vTap subject
* @param prevSubject previous vTap subject
* @param type openstack vtap event type
* @param vtap event openstack vtap subject
* @param prevVtap previous openstack vtap subject
*/
public OpenstackVtapEvent(Type type, OpenstackVtap vTap, OpenstackVtap prevSubject) {
super(type, vTap);
if (type == Type.VTAP_UPDATED) {
this.prevSubject = prevSubject;
}
public OpenstackVtapEvent(Type type, OpenstackVtap vtap, OpenstackVtap prevVtap) {
super(type, vtap);
prevSubject = prevVtap;
}
/**
* Gets the previous subject in this vTap event.
* Creates an event of a given type and for the specified openstack vtap and time.
*
* @param type openstack vtap event type
* @param vtap event openstack vtap subject
* @param prevVtap previous openstack vtap subject
* @param time occurrence time
*/
public OpenstackVtapEvent(Type type, OpenstackVtap vtap, OpenstackVtap prevVtap, long time) {
super(type, vtap, time);
prevSubject = prevVtap;
}
/**
* Gets the previous subject in this openstack vtap event.
*
* @return the previous subject, or null if previous subject is not
* specified.
*/
public OpenstackVtap prevSubject() {
return this.prevSubject;
public Object prevSubject() {
return prevSubject;
}
/**
* Gets the openstack vtap network in this openstack vtap event.
*
* @return the subject, or null if the type is removed
*/
public OpenstackVtapNetwork openstackVtapNetwork() {
Object obj = subject();
checkState(obj == null || obj instanceof OpenstackVtapNetwork, INVALID_OBJ_TYPE, obj);
return (OpenstackVtapNetwork) obj;
}
/**
* Gets the previous openstack vtap network in this openstack vtap event.
*
* @return the previous subject, or null if type is added
*/
public OpenstackVtapNetwork prevOpenstackVtapNetwork() {
Object obj = prevSubject;
checkState(obj == null || obj instanceof OpenstackVtapNetwork, INVALID_OBJ_TYPE, obj);
return (OpenstackVtapNetwork) obj;
}
/**
* Gets the openstack vtap in this openstack vtap event.
*
* @return the subject, or null if the type is removed
*/
public OpenstackVtap openstackVtap() {
Object obj = subject();
checkState(obj == null || obj instanceof OpenstackVtap, INVALID_OBJ_TYPE, obj);
return (OpenstackVtap) obj;
}
/**
* Gets the previous openstack vtap in this openstack vtap event.
*
* @return the previous subject, or null if type is added
*/
public OpenstackVtap prevOpenstackVtap() {
Object obj = prevSubject;
checkState(obj == null || obj instanceof OpenstackVtap, INVALID_OBJ_TYPE, obj);
return (OpenstackVtap) obj;
}
@Override

View File

@ -19,12 +19,12 @@ import java.util.Objects;
import java.util.UUID;
/**
* Immutable representation of an openstack vTap identifier.
* Immutable representation of an openstack vtap identifier.
*/
public final class OpenstackVtapId {
/**
* Represents either no vTap, or an unspecified vTap.
* Represents either no vtap, or an unspecified vtap.
*/
public static final OpenstackVtapId NONE = new OpenstackVtapId(null);
@ -50,35 +50,35 @@ public final class OpenstackVtapId {
}
/**
* Creates a vTap identifier using the supplied UUID.
* Creates a vtap identifier using the supplied UUID.
*
* @param uuid vTap UUID
* @return vTap identifier
* @param uuid vtap UUID
* @return vtap identifier
*/
public static OpenstackVtapId vTapId(UUID uuid) {
public static OpenstackVtapId vtapId(UUID uuid) {
return new OpenstackVtapId(uuid);
}
/**
* Creates a vTap identifier using the supplied string format of UUID.
* Creates a vtap identifier using the supplied string format of UUID.
*
* @param uuidString vTap UUID
* @return vTap identifier
* @param uuidString vtap UUID
* @return vtap identifier
*/
public static OpenstackVtapId vTapId(String uuidString) {
public static OpenstackVtapId vtapId(String uuidString) {
try {
return vTapId(UUID.fromString(uuidString));
return vtapId(UUID.fromString(uuidString));
} catch (Exception e) {
throw new IllegalArgumentException("Invalid UUID string: " + uuidString);
}
}
/**
* Creates a OpenstackVtap id using random uuid.
* Creates a openstack vtap id using random uuid.
*
* @return OpenstackVtap identifier
* @return openstack vtap identifier
*/
public static OpenstackVtapId vTapId() {
public static OpenstackVtapId vtapId() {
return new OpenstackVtapId(UUID.randomUUID());
}

View File

@ -18,7 +18,7 @@ package org.onosproject.openstackvtap.api;
import org.onosproject.event.EventListener;
/**
* Entity capable of receiving user related events.
* Entity capable of receiving openstack vtap related events.
*/
public interface OpenstackVtapListener extends EventListener<OpenstackVtapEvent> {
}

View File

@ -0,0 +1,106 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openstackvtap.api;
import org.onlab.packet.IpAddress;
import org.onosproject.net.Annotated;
import org.onosproject.net.SparseAnnotations;
/**
* Abstraction of an openstack vtap network.
*/
public interface OpenstackVtapNetwork extends Annotated {
/**
* List of valid openstack vtap tunneling modes.
*/
enum Mode {
/**
* Indicates GRE tunneling.
*/
GRE,
/**
* Indicates VXLAN tunneling.
*/
VXLAN
}
/**
* Returns the OpenstackVtapNetwork mode.
*
* @return mode of vtap tunneling
*/
Mode mode();
/**
* Returns the network id of the vtap tunneling.
*
* @return networkId (e.g., gre key, vxlan vni)
*/
Integer networkId();
/**
* Returns the vtap server IP address used for tunneling.
*
* @return ip address for vtap server
*/
IpAddress serverIp();
/**
* Builder of new OpenstackVtapNetwork instance.
*/
interface Builder {
/**
* Returns openstack vtap network builder with supplied OpenstackVtapNetwork mode.
*
* @param mode mode of vtap tunneling
* @return openstack vtap network builder
*/
Builder mode(Mode mode);
/**
* Returns openstack vtap network builder with supplied networkId for tunneling.
*
* @param networkId (e.g., gre key, vxlan vni)
* @return openstack vtap network builder
*/
Builder networkId(Integer networkId);
/**
* Returns openstack vtap network builder with supplied server IP address.
*
* @param serverIp ip address for vtap server
* @return openstack vtap network builder
*/
Builder serverIp(IpAddress serverIp);
/**
* Returns openstack vtap network builder with supplied annotations.
*
* @param annotations a set of annotations
* @return openstack vtap network builder
*/
Builder annotations(SparseAnnotations annotations);
/**
* Builds an immutable OpenstackVtapNetwork instance.
*
* @return OpenstackVtapNetwork instance
*/
OpenstackVtapNetwork build();
}
}

View File

@ -15,47 +15,111 @@
*/
package org.onosproject.openstackvtap.api;
import org.onlab.packet.IpAddress;
import org.onosproject.event.ListenerService;
import org.onosproject.net.DeviceId;
import java.util.Set;
/**
* Service for interacting with the inventory of vTap.
* Service for interacting with the inventory of openstack vtap.
*/
public interface OpenstackVtapService
extends ListenerService<OpenstackVtapEvent, OpenstackVtapListener> {
/**
* Returns the number of vTaps in the store.
* Creates a new openstack vtap network based on the specified description.
*
* @param type vTap type
* @return vTap count
* @param mode mode of vtap network
* @param networkId network id of the vtap tunneling network
* @param serverIp server IP address used for tunneling
* @return created openstack vtap network object or null if error occurred
*/
OpenstackVtapNetwork createVtapNetwork(OpenstackVtapNetwork.Mode mode, Integer networkId, IpAddress serverIp);
/**
* Updates the openstack vtap network based on the specified description.
*
* @param description description of vtap network
* @return updated openstack vtap network object or null if error occurred
*/
OpenstackVtapNetwork updateVtapNetwork(OpenstackVtapNetwork description);
/**
* Removes the specified openstack vtap network.
*
* @return removed openstack vtap network object or null if error occurred
*/
OpenstackVtapNetwork removeVtapNetwork();
/**
* Returns the openstack vtap network.
*
* @return openstack vtap network or null if not exists
*/
OpenstackVtapNetwork getVtapNetwork();
/**
* Returns a set of devices which are associated with the openstack vtap network.
*
* @return set of devices
*/
Set<DeviceId> getVtapNetworkDevices();
/**
* Creates a new openstack vtap based on the specified type and criterion.
*
* @param type type of vtap (all,rx,tx)
* @param vtapCriterion criterion of vtap
* @return created openstack vtap object or null if error occurred
*/
OpenstackVtap createVtap(OpenstackVtap.Type type, OpenstackVtapCriterion vtapCriterion);
/**
* Updates the openstack vtap with specified description.
*
* @param description description of vtap
* @return updated openstack vtap object or null if error occurred
*/
OpenstackVtap updateVtap(OpenstackVtap description);
/**
* Removes the specified openstack vtap with given vtap identifier.
*
* @param vtapId vtap identifier
* @return removed openstack vtap object or null if error occurred
*/
OpenstackVtap removeVtap(OpenstackVtapId vtapId);
/**
* Returns the number of openstack vtaps for the given type.
*
* @param type type of vtap (any,rx,tx,all)
* @return number of openstack vtaps
*/
int getVtapCount(OpenstackVtap.Type type);
/**
* Returns a collection of selected vTaps in the store.
* Returns a set of openstack vtaps for the given type.
*
* @param type vTap type
* @return iterable collection of selected vTaps
* @param type type of vtap (any,rx,tx,all)
* @return set of openstack vtaps
*/
Set<OpenstackVtap> getVtaps(OpenstackVtap.Type type);
/**
* Returns the vTap with the specified identifier.
* Returns the openstack vtap with the specified identifier.
*
* @param vTapId vTap identifier
* @return vTap or null if not exist
* @param vtapId vtap identifier
* @return openstack vtap or null if one with the given identifier is not known
*/
OpenstackVtap getVtap(OpenstackVtapId vTapId);
OpenstackVtap getVtap(OpenstackVtapId vtapId);
/**
* Returns a collection of vTaps which are associated with the given device.
* Returns a set of openstack vtaps which are associated with the given device.
*
* @param type vTap type
* @param deviceId device identifier
* @return a set of vTaps
* @param deviceId device identifier
* @return set of openstack vtaps
*/
Set<OpenstackVtap> getVtapsByDeviceId(OpenstackVtap.Type type, DeviceId deviceId);
Set<OpenstackVtap> getVtapsByDeviceId(DeviceId deviceId);
}

View File

@ -21,92 +21,162 @@ import org.onosproject.store.Store;
import java.util.Set;
/**
* Manages inventory of OpenstackVtap states; not intended for direct use.
* Manages inventory of openstack vtap datum; not intended for direct use.
*/
public interface OpenstackVtapStore
extends Store<OpenstackVtapEvent, OpenstackVtapStoreDelegate> {
/**
* Creates a new vTap or updates the existing one based on the specified
* description.
* Creates a new openstack vtap network based on the specified description.
*
* @param vTapId vTap identifier
* @param description vTap description data
* @param replaceFlag replace device set if true, merge device set otherwise
* @return created or updated vTap object or null if error occurred
* @param key vtap network identifier
* @param description description of vtap network
* @return created openstack vtap network object or null if error occurred
*/
OpenstackVtap createOrUpdateVtap(OpenstackVtapId vTapId, OpenstackVtap description, boolean replaceFlag);
OpenstackVtapNetwork createVtapNetwork(Integer key, OpenstackVtapNetwork description);
/**
* Removes the specified vTap from the inventory by the given vTap identifier.
* Updates the openstack vtap network based on the specified description.
*
* @param vTapId vTap identifier
* @return removed vTap object or null if error occurred
* @param key vtap network identifier
* @param description description of vtap network
* @return updated openstack vtap network object or null if error occurred
*/
OpenstackVtap removeVtapById(OpenstackVtapId vTapId);
OpenstackVtapNetwork updateVtapNetwork(Integer key, OpenstackVtapNetwork description);
/**
* Adds the specified device id from the vTap entry.
* Removes the specified openstack vtap network with the specified identifier.
*
* @param vTapId vTap identification
* @param type vTap type
* @param deviceId device identifier to be added
* @param key vtap network identifier
* @return removed openstack vtap network object or null if error occurred
*/
OpenstackVtapNetwork removeVtapNetwork(Integer key);
/**
* Removes all openstack vtap networks.
*/
void clearVtapNetworks();
/**
* Returns the number of openstack vtap networks.
*
* @return number of openstack vtap networks
*/
int getVtapNetworkCount();
/**
* Returns the openstack vtap network with the specified identifier.
*
* @param key vtap network identifier
* @return openstack vtap or null if one with the given identifier is not known
*/
OpenstackVtapNetwork getVtapNetwork(Integer key);
/**
* Adds the specified device id to the specified vtap network entry.
*
* @param key vtap network identifier
* @param deviceId device identifier to be added
* @return true on success, false otherwise
*/
boolean addDeviceToVtap(OpenstackVtapId vTapId, OpenstackVtap.Type type, DeviceId deviceId);
boolean addDeviceToVtapNetwork(Integer key, DeviceId deviceId);
/**
* Removes the specified device id from the vTap entry.
* Removes the specified device id from the specified vtap network entry.
*
* @param vTapId vTap identification
* @param type vTap type
* @param deviceId device identifier to be removed
* @param key vtap network identifier
* @param deviceId device identifier to be removed
* @return true on success, false otherwise
*/
boolean removeDeviceFromVtap(OpenstackVtapId vTapId, OpenstackVtap.Type type, DeviceId deviceId);
boolean removeDeviceFromVtapNetwork(Integer key, DeviceId deviceId);
/**
* Adds the specified device id from the vTap entry.
* Returns a set of device identifiers from the specified vtap network entry.
*
* @param vTapId vTap identification
* @param txDeviceIds TX device identifiers to be updated
* @param rxDeviceIds RX device identifiers to be updated
* @param replaceFlag replace device set if true, merge device set otherwise
* @return true on success, false otherwise
* @param key vtap network identifier
* @return set of device identifier
*/
boolean updateDeviceForVtap(OpenstackVtapId vTapId, Set<DeviceId> txDeviceIds,
Set<DeviceId> rxDeviceIds, boolean replaceFlag);
Set<DeviceId> getVtapNetworkDevices(Integer key);
/**
* Returns the number of vTaps in the store.
* Creates a new openstack vtap based on the specified description.
*
* @param type vTap type
* @return vTap count
* @param description description of vtap
* @return created openstack vtap object or null if error occurred
*/
OpenstackVtap createVtap(OpenstackVtap description);
/**
* Updates the openstack vtap with specified description.
*
* @param description description of vtap
* @param replaceDevices replace device set if true, merge device set otherwise
* @return updated openstack vtap object or null if error occurred
*/
OpenstackVtap updateVtap(OpenstackVtap description, boolean replaceDevices);
/**
* Removes the specified openstack vtap with given vtap identifier.
*
* @param vtapId vtap identifier
* @return removed openstack vtap object or null if error occurred
*/
OpenstackVtap removeVtap(OpenstackVtapId vtapId);
/**
* Removes all openstack vtaps.
*/
void clearVtaps();
/**
* Returns the number of openstack vtaps for the given type.
*
* @param type type of vtap (any,rx,tx,all)
* @return number of openstack vtaps
*/
int getVtapCount(OpenstackVtap.Type type);
/**
* Returns a collection of selected vTaps in the store.
* Returns a set of openstack vtaps for the given type.
*
* @param type vTap type
* @return iterable collection of selected vTaps
* @param type type of vtap (any,rx,tx,all)
* @return set of openstack vtaps
*/
Set<OpenstackVtap> getVtaps(OpenstackVtap.Type type);
/**
* Returns the vTap with the specified identifier.
* Returns the openstack vtap with the specified identifier.
*
* @param vTapId vTap identifier
* @return vtap or null if not found
* @param vtapId vtap identifier
* @return openstack vtap or null if one with the given identifier is not known
*/
OpenstackVtap getVtap(OpenstackVtapId vTapId);
OpenstackVtap getVtap(OpenstackVtapId vtapId);
/**
* Returns the set of vTaps whose included on device.
* Adds the specified device id to the specified vtap entry.
*
* @param type vTap type
* @param deviceId device identifier
* @return set of vTaps
* @param vtapId vtap identifier
* @param type type of vtap (any,rx,tx,all)
* @param deviceId device identifier to be added
* @return true on success, false otherwise
*/
Set<OpenstackVtap> getVtapsByDeviceId(OpenstackVtap.Type type, DeviceId deviceId);
boolean addDeviceToVtap(OpenstackVtapId vtapId, OpenstackVtap.Type type, DeviceId deviceId);
/**
* Removes the specified device id from the vtap entry.
*
* @param vtapId vtap identifier
* @param type type of vtap (any,rx,tx,all)
* @param deviceId device identifier to be removed
* @return true on success, false otherwise
*/
boolean removeDeviceFromVtap(OpenstackVtapId vtapId, OpenstackVtap.Type type, DeviceId deviceId);
/**
* Returns a set of openstack vtaps which are associated with the given device.
*
* @param deviceId device identifier
* @return set of openstack vtaps
*/
Set<OpenstackVtap> getVtapsByDeviceId(DeviceId deviceId);
}

View File

@ -15,6 +15,6 @@
*/
/**
* Application API for Openstack vTap.
* Application API for openstack vtap.
*/
package org.onosproject.openstackvtap.api;

View File

@ -25,8 +25,8 @@ osgi_jar_with_tests (
deps = COMPILE_DEPS,
test_deps = TEST_DEPS,
web_context = '/onos/openstackvtap',
api_title = 'OpenStack Network vTap REST API',
api_title = 'OpenStack Vtap REST API',
api_version = '1.0',
api_description = 'OpenStack Network vTap REST API',
api_description = 'OpenStack Vtap REST API',
api_package = 'org.onosproject.openstackvtap.web',
)

View File

@ -12,9 +12,9 @@ TEST_DEPS = TEST_ADAPTERS + TEST_REST + [
]
osgi_jar_with_tests(
api_description = "OpenStack Network vTap REST API",
api_description = "Openstack Vtap REST API",
api_package = "org.onosproject.openstackvtap.web",
api_title = "OpenStack Network vTap REST API",
api_title = "Openstack Vtap REST API",
api_version = "1.0",
test_deps = TEST_DEPS,
web_context = "/onos/openstackvtap",

View File

@ -15,7 +15,7 @@
~ limitations under the License.
-->
<app name="org.onosproject.openstackvtap" origin="Open Networking Foundation"
version="${project.version}" category="Utility" title="OpenStack vTap App"
version="${project.version}" category="Utility" title="Openstack Vtap App"
features="${project.artifactId}" apps="org.onosproject.openstacknetworking"
featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features">
<description>${project.description}</description>

View File

@ -28,13 +28,13 @@ import static org.onosproject.openstackvtap.util.OpenstackVtapUtil.getProtocolTy
import static org.onosproject.openstackvtap.util.OpenstackVtapUtil.getVtapTypeFromString;
/**
* Command line interface for adding openstack vTap rule.
* Adds a openstack vtap rule.
*/
@Command(scope = "onos", name = "openstack-vtap-add",
description = "OpenstackVtap activate")
public class OpenstackVtapAddCommand extends AbstractShellCommand {
private final OpenstackVtapAdminService vTapService =
private final OpenstackVtapAdminService vtapService =
get(OpenstackVtapAdminService.class);
@Argument(index = 0, name = "srcIp",
@ -48,9 +48,9 @@ public class OpenstackVtapAddCommand extends AbstractShellCommand {
String dstIp = "";
@Argument(index = 2, name = "ipProto",
description = "IP protocol [tcp|udp|icmp|none]",
description = "IP protocol [any|tcp|udp|icmp]",
required = false, multiValued = false)
String ipProto = "";
String ipProto = "any";
@Argument(index = 3, name = "srcTpPort",
description = "source transport layer port (0 is skip)",
@ -63,43 +63,42 @@ public class OpenstackVtapAddCommand extends AbstractShellCommand {
int dstTpPort = 0;
@Argument(index = 5, name = "type",
description = "vTap type [all|tx|rx]",
description = "vtap type [all|rx|tx]",
required = false, multiValued = false)
String vTapTypeStr = "all";
String vtapTypeStr = "all";
@Override
protected void execute() {
DefaultOpenstackVtapCriterion.Builder
defaultVtapCriterionBuilder = DefaultOpenstackVtapCriterion.builder();
if (makeCriterion(defaultVtapCriterionBuilder)) {
OpenstackVtap.Type type = getVtapTypeFromString(vTapTypeStr);
DefaultOpenstackVtapCriterion.Builder vtapCriterionBuilder = DefaultOpenstackVtapCriterion.builder();
if (makeCriterion(vtapCriterionBuilder)) {
OpenstackVtap.Type type = getVtapTypeFromString(vtapTypeStr);
if (type == null) {
print("Invalid vTap type");
print("Invalid vtap type");
return;
}
OpenstackVtap vTap = vTapService.createVtap(type, defaultVtapCriterionBuilder.build());
if (vTap != null) {
print("Created OpenstackVtap with id { %s }", vTap.id().toString());
OpenstackVtap vtap = vtapService.createVtap(type, vtapCriterionBuilder.build());
if (vtap != null) {
print("Created OpenstackVtap with id { %s }", vtap.id().toString());
} else {
print("Failed to create OpenstackVtap");
}
}
}
private boolean makeCriterion(DefaultOpenstackVtapCriterion.Builder vTapCriterionBuilder) {
private boolean makeCriterion(DefaultOpenstackVtapCriterion.Builder vtapCriterionBuilder) {
try {
vTapCriterionBuilder.srcIpPrefix(IpPrefix.valueOf(srcIp));
vTapCriterionBuilder.dstIpPrefix(IpPrefix.valueOf(dstIp));
vtapCriterionBuilder.srcIpPrefix(IpPrefix.valueOf(srcIp));
vtapCriterionBuilder.dstIpPrefix(IpPrefix.valueOf(dstIp));
} catch (Exception e) {
print("Inputted valid source IP & destination IP in CIDR (e.g., \"10.1.0.4/32\")");
return false;
}
vTapCriterionBuilder.ipProtocol(getProtocolTypeFromString(ipProto.toLowerCase()));
vtapCriterionBuilder.ipProtocol(getProtocolTypeFromString(ipProto.toLowerCase()));
vTapCriterionBuilder.srcTpPort(TpPort.tpPort(srcTpPort));
vTapCriterionBuilder.dstTpPort(TpPort.tpPort(dstTpPort));
vtapCriterionBuilder.srcTpPort(TpPort.tpPort(srcTpPort));
vtapCriterionBuilder.dstTpPort(TpPort.tpPort(dstTpPort));
return true;
}

View File

@ -22,25 +22,25 @@ import org.onosproject.openstackvtap.api.OpenstackVtapAdminService;
import org.onosproject.openstackvtap.api.OpenstackVtapId;
/**
* Command line interface for removing openstack vTap rule.
* Delete a openstack vtap rule from the existing vtaps.
*/
@Command(scope = "onos", name = "openstack-vtap-del",
description = "OpenstackVtap deactivate")
public class OpenstackVtapDeleteCommand extends AbstractShellCommand {
private final OpenstackVtapAdminService vTapService = get(OpenstackVtapAdminService.class);
private final OpenstackVtapAdminService vtapService = get(OpenstackVtapAdminService.class);
@Argument(index = 0, name = "id", description = "vTap ID",
@Argument(index = 0, name = "id", description = "vtap ID",
required = true, multiValued = false)
String vTapId = "";
String vtapId = "";
@Override
protected void execute() {
OpenstackVtap vTap = vTapService.removeVtap(OpenstackVtapId.vTapId(vTapId));
if (vTap != null) {
print("Removed OpenstackVtap with id { %s }", vTap.id().toString());
OpenstackVtap vtap = vtapService.removeVtap(OpenstackVtapId.vtapId(vtapId));
if (vtap != null) {
print("Removed OpenstackVtap with id { %s }", vtap.id().toString());
} else {
print("Failed to remove OpenstackVtap with id { %s }", vTapId);
print("Failed to remove OpenstackVtap with id { %s }", vtapId);
}
}
}

View File

@ -15,46 +15,66 @@
*/
package org.onosproject.openstackvtap.cli;
import com.google.common.collect.ImmutableSet;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.DeviceId;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeService;
import org.onosproject.openstackvtap.api.OpenstackVtap;
import org.onosproject.openstackvtap.api.OpenstackVtapService;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import static org.onosproject.openstackvtap.util.OpenstackVtapUtil.getVtapTypeFromString;
/**
* Command line interface for listing openstack vTap rules.
* Lists openstack vtap rules.
*/
@Command(scope = "onos", name = "openstack-vtap-list",
description = "OpenstackVtap list")
public class OpenstackVtapListCommand extends AbstractShellCommand {
private final OpenstackVtapService vTapService = get(OpenstackVtapService.class);
private final OpenstackVtapService vtapService = get(OpenstackVtapService.class);
private final OpenstackNodeService osNodeService = get(OpenstackNodeService.class);
@Argument(index = 0, name = "type",
description = "vTap type [all|tx|rx]",
description = "vtap type [any|all|rx|tx]",
required = false, multiValued = false)
String vTapType = "none";
String vtapType = "any";
private static final String FORMAT = "ID { %s }: type [%s], srcIP [%s], dstIP [%s]";
private static final String FORMAT_TX_DEVICES = " tx devices: %s";
private static final String FORMAT_RX_DEVICES = " rx devices: %s";
private static final String FORMAT_TX_NODES = " tx openstack nodes: %s";
private static final String FORMAT_RX_NODES = " rx openstack nodes: %s";
@Override
protected void execute() {
OpenstackVtap.Type type = getVtapTypeFromString(vTapType);
Set<OpenstackVtap> openstackVtaps = vTapService.getVtaps(type);
for (OpenstackVtap vTap : openstackVtaps) {
OpenstackVtap.Type type = getVtapTypeFromString(vtapType);
Set<OpenstackVtap> openstackVtaps = vtapService.getVtaps(type);
for (OpenstackVtap vtap : openstackVtaps) {
print(FORMAT,
vTap.id().toString(),
vTap.type().toString(),
vTap.vTapCriterion().srcIpPrefix().toString(),
vTap.vTapCriterion().dstIpPrefix().toString());
print(FORMAT_TX_DEVICES, vTap.txDeviceIds());
print(FORMAT_RX_DEVICES, vTap.rxDeviceIds());
vtap.id().toString(),
vtap.type().toString(),
vtap.vtapCriterion().srcIpPrefix().toString(),
vtap.vtapCriterion().dstIpPrefix().toString());
print(FORMAT_TX_NODES, osNodeNames(vtap.txDeviceIds()));
print(FORMAT_RX_NODES, osNodeNames(vtap.rxDeviceIds()));
}
}
private Set<String> osNodeNames(Set<DeviceId> deviceIds) {
if (deviceIds == null) {
return ImmutableSet.of();
} else {
return deviceIds.parallelStream()
.map(osNodeService::node)
.filter(Objects::nonNull)
.map(OpenstackNode::hostname)
.collect(Collectors.toSet());
}
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openstackvtap.cli;
import com.google.common.collect.ImmutableSet;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.DeviceId;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeService;
import org.onosproject.openstackvtap.api.OpenstackVtapAdminService;
import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Lists openstack vtap networks.
*/
@Command(scope = "onos", name = "openstack-vtap-network-list",
description = "OpenstackVtap network list")
public class OpenstackVtapNetworkListCommand extends AbstractShellCommand {
private final OpenstackVtapAdminService osVtapAdminService = get(OpenstackVtapAdminService.class);
private final OpenstackNodeService osNodeService = get(OpenstackNodeService.class);
private static final String FORMAT = "mode [%s], networkId [%d], serverIp [%s]";
private static final String FORMAT_NODES = " openstack nodes: %s";
@Override
protected void execute() {
OpenstackVtapNetwork vtapNetwork = osVtapAdminService.getVtapNetwork();
if (vtapNetwork != null) {
print(FORMAT,
vtapNetwork.mode().toString(),
vtapNetwork.networkId() != null ? vtapNetwork.networkId() : "N/A",
vtapNetwork.serverIp().toString());
print(FORMAT_NODES, osNodeNames(osVtapAdminService.getVtapNetworkDevices()));
}
}
private Set<String> osNodeNames(Set<DeviceId> deviceIds) {
if (deviceIds == null) {
return ImmutableSet.of();
} else {
return deviceIds.parallelStream()
.map(osNodeService::node)
.filter(Objects::nonNull)
.map(OpenstackNode::hostname)
.collect(Collectors.toSet());
}
}
}

View File

@ -1,79 +0,0 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openstackvtap.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.packet.VlanId;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
import org.onosproject.openstackvtap.api.OpenstackVtap;
import org.onosproject.openstackvtap.api.OpenstackVtapAdminService;
import static org.onlab.packet.VlanId.UNTAGGED;
import static org.onosproject.openstackvtap.util.OpenstackVtapUtil.getVtapTypeFromString;
/**
* Command line interface for set openstack vTap output.
*/
@Command(scope = "onos", name = "openstack-vtap-output",
description = "OpenstackVtap output setup")
public class OpenstackVtapOutputCommand extends AbstractShellCommand {
private final DeviceService deviceService = get(DeviceService.class);
private final OpenstackVtapAdminService vTapAdminService =
get(OpenstackVtapAdminService.class);
@Argument(index = 0, name = "deviceId", description = "device id",
required = true, multiValued = false)
String id = "";
@Argument(index = 1, name = "port", description = "output port number",
required = true, multiValued = false)
int port = 0;
@Argument(index = 2, name = "vlan", description = "vlan id",
required = false, multiValued = false)
int vlan = UNTAGGED;
@Argument(index = 3, name = "type", description = "vTap type [all|tx|rx]",
required = false, multiValued = false)
String vTapTypeStr = "all";
@Override
protected void execute() {
try {
Device device = deviceService.getDevice(DeviceId.deviceId(id));
if (device != null) {
OpenstackVtap.Type type = getVtapTypeFromString(vTapTypeStr);
vTapAdminService.setVtapOutput(device.id(), type,
PortNumber.portNumber(port), VlanId.vlanId((short) vlan));
print("Set OpenstackVtap output deviceId { %s }, port=%s, vlan=%s",
device.id().toString(),
PortNumber.portNumber(port).toString(),
VlanId.vlanId((short) vlan).toString());
} else {
print("Invalid device id");
}
} catch (Exception e) {
print("Invalid parameter: %s", e.toString());
}
}
}

View File

@ -28,10 +28,10 @@ public class ProtocolTypeCompleter extends AbstractChoicesCompleter {
@Override
protected List<String> choices() {
List<String> strings = Lists.newArrayList();
strings.add("any");
strings.add("tcp");
strings.add("udp");
strings.add("icmp");
strings.add("none");
return strings;
}
}

View File

@ -27,11 +27,11 @@ import java.util.SortedSet;
import static org.onosproject.openstackvtap.util.OpenstackVtapUtil.getVtapTypeFromString;
/**
* vTap ID completer.
* Vtap ID completer.
*/
public class VtapIdCompleter implements Completer {
private static final String VTAP_TYPE = "none";
private static final String VTAP_TYPE = "any";
@Override
public int complete(String buffer, int cursor, List<String> candidates) {

View File

@ -21,16 +21,17 @@ import org.onosproject.cli.AbstractChoicesCompleter;
import java.util.List;
/**
* vTap type completer.
* Vtap type completer.
*/
public class VtapTypeCompleter extends AbstractChoicesCompleter {
@Override
protected List<String> choices() {
List<String> strings = Lists.newArrayList();
strings.add("tx");
strings.add("rx");
strings.add("all");
strings.add("rx");
strings.add("tx");
strings.add("any");
return strings;
}
}

View File

@ -15,6 +15,6 @@
*/
/**
* Console commands for OpenStack vtap.
* Console commands for openstack vtap.
*/
package org.onosproject.openstackvtap.cli;

View File

@ -0,0 +1,73 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openstackvtap.codec;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.packet.IpAddress;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
import org.onosproject.openstackvtap.impl.DefaultOpenstackVtapNetwork;
import org.slf4j.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Openstack vtap network codec used for serializing and de-serializing JSON string.
*/
public final class OpenstackVtapNetworkCodec extends JsonCodec<OpenstackVtapNetwork> {
private final Logger log = getLogger(getClass());
private static final String MODE = "mode";
private static final String NETWORK_ID = "networkId";
private static final String SERVER_IP = "serverIp";
private static final String NODES = "nodes";
private static final String JSON_NULL_MESSAGE = "% cannot be null";
private static final String JSON_MISSING_MESSAGE = "% is required";
private static final String JSON_TYPE_MESSAGE = "% is not json object type";
@Override
public ObjectNode encode(OpenstackVtapNetwork network, CodecContext context) {
checkNotNull(network, JSON_NULL_MESSAGE, "OpenstackVtapNetwork object");
ObjectNode result = context.mapper().createObjectNode()
.put(MODE, network.mode().toString())
.put(NETWORK_ID, network.networkId())
.put(SERVER_IP, network.serverIp().toString());
return result;
}
@Override
public OpenstackVtapNetwork decode(ObjectNode json, CodecContext context) {
checkNotNull(json, JSON_NULL_MESSAGE, "OpenstackVtapNetwork json");
checkState(json.isObject(), JSON_TYPE_MESSAGE, "OpenstackVtapNetwork json");
DefaultOpenstackVtapNetwork.Builder builder = DefaultOpenstackVtapNetwork.builder()
.mode(OpenstackVtapNetwork.Mode.valueOf(checkNotNull(json.get(MODE).asText(null),
JSON_MISSING_MESSAGE, MODE)))
.networkId(json.get(NETWORK_ID).asInt(0))
.serverIp(IpAddress.valueOf(checkNotNull(json.get(SERVER_IP).asText(null),
JSON_MISSING_MESSAGE, SERVER_IP)));
log.debug("OpenstackVtapNetwork is {}", builder.build().toString());
return builder.build();
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Implementations of the codec broker and openstack vtap entity JSON codecs.
*/
package org.onosproject.openstackvtap.codec;

View File

@ -0,0 +1,85 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openstackvtap.gui;
import com.google.common.collect.ImmutableList;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.ui.UiExtensionService;
import org.onosproject.ui.UiMessageHandlerFactory;
import org.onosproject.ui.UiTopoOverlayFactory;
import org.onosproject.ui.UiView;
import org.onosproject.ui.UiViewHidden;
import org.onosproject.ui.UiExtension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* Mechanism to stream data to the GUI.
*/
@Component(immediate = true, enabled = true)
@Service(value = OpenstackVtapUI.class)
public class OpenstackVtapUI {
private static final String OPENSTACK_VTAP_ID = "openstackvtap";
private static final String RESOURCE_PATH = "gui";
private static final ClassLoader CL = OpenstackVtapUI.class.getClassLoader();
private final Logger log = LoggerFactory.getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected UiExtensionService uiExtensionService;
// Factory for UI message handlers
private final UiMessageHandlerFactory messageHandlerFactory =
() -> ImmutableList.of(new OpenstackVtapViewMessageHandler());
// List of application views
private final List<UiView> views = ImmutableList.of(
new UiViewHidden(OPENSTACK_VTAP_ID)
);
// Factory for UI topology overlays
private final UiTopoOverlayFactory topoOverlayFactory =
() -> ImmutableList.of(
new OpenstackVtapUiTopovOverlay()
);
// Application UI extension
private final UiExtension uiExtension =
new UiExtension.Builder(CL, views)
.messageHandlerFactory(messageHandlerFactory)
.resourcePath(RESOURCE_PATH)
.topoOverlayFactory(topoOverlayFactory)
.build();
@Activate
protected void activate() {
uiExtensionService.register(uiExtension);
log.info("Started");
}
@Deactivate
protected void deactivate() {
uiExtensionService.unregister(uiExtension);
log.info("Stopped");
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openstackvtap.gui;
import org.onosproject.ui.UiTopoOverlay;
public class OpenstackVtapUiTopovOverlay extends UiTopoOverlay {
private static final String OVERLAY_ID = "vtap-overlay";
public OpenstackVtapUiTopovOverlay() {
super(OVERLAY_ID);
}
@Override
public void activate() {
super.activate();
log.debug("Openstack VtapOverlay Activated");
}
@Override
public void deactivate() {
super.deactivate();
log.debug("Openstack VtapOverlay Deactivated");
}
}

View File

@ -0,0 +1,230 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openstackvtap.gui;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.IpAddress;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.net.host.HostService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Set;
import java.util.Iterator;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.TpPort;
import org.onosproject.openstackvtap.api.OpenstackVtap;
import org.onosproject.openstackvtap.api.OpenstackVtapAdminService;
import org.onosproject.openstackvtap.impl.DefaultOpenstackVtapCriterion;
import static org.onosproject.openstackvtap.util.OpenstackVtapUtil.getProtocolTypeFromString;
import static org.onosproject.openstackvtap.util.OpenstackVtapUtil.getVtapTypeFromString;
import static org.onosproject.net.HostId.hostId;
/**
* Message handler for Openstack Vtap related messages.
*/
public class OpenstackVtapViewMessageHandler extends UiMessageHandler {
private final Logger log = LoggerFactory.getLogger(getClass());
private static final String OSV_IS_ACTIVATED_REQ = "openstackVtapIsActivatedRequest";
private static final String OSV_IS_ACTIVATED_RESP = "openstackVtapIsActivatedResponse";
private static final String OSV_CREATE_REQ = "openstackVtapCreateRequest";
private static final String OSV_CREATE_RESP = "openstackVtapCreateResponse";
private static final String SOURCE = "src";
private static final String DESTINATION = "dst";
private static final String SOURCE_IP = "srcIp";
private static final String DESTINATION_IP = "dstIp";
private static final String SOURCE_TRANSPORT_PORT = "srcPort";
private static final String DESTINATION_TRANSPORT_PORT = "dstPort";
private static final String SOURCE_HOST_NAME = "srcName";
private static final String DESTINATION_HOST_NAME = "dstName";
private static final String IP_PROTOCOL = "ipProto";
private static final String VTAP_TYPE = "vtapType";
private static final String IP_PROTOCOL_LIST = "ipProtoList";
private static final String VTAP_TYPE_LIST = "vtapTypeList";
private static final String RESULT = "result";
private static final String VALUE = "value";
private static final String SUCCESS = "Success";
private static final String FAILED = "Failed";
private static final String INVALID_VTAP_TYPE = "Invalid vtap type";
private static final String FAILED_TO_CREATE_VTAP = "Failed to create OpenstackVtap";
private static final String WRONG_IP_ADDRESS =
"Inputted valid source & destination IP in CIDR (e.g., \"10.1.0.4/32\")";
private static final String INVALID_TRANSPORT_PORT =
"Invalid source & destination transport port has been entered";
private static final String[] IP_PROTOCOL_ARRAY = {"Any", "TCP", "UDP", "ICMP"};
private static final String[] VTAP_TYPE_ARRAY = {"All", "RX", "TX"};
private HostService hostService;
private OpenstackVtapAdminService vtapService;
@Override
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
hostService = directory.get(HostService.class);
vtapService = directory.get(OpenstackVtapAdminService.class);
}
@Override
protected Collection<RequestHandler> createRequestHandlers() {
return ImmutableSet.of(
new VtapIsActivatedRequestHandler(),
new VtapCreateRequestHandler()
);
}
private final class VtapIsActivatedRequestHandler extends RequestHandler {
private VtapIsActivatedRequestHandler() {
super(OSV_IS_ACTIVATED_REQ);
}
@Override
public void process(ObjectNode payload) {
String srcId = string(payload, SOURCE, null);
String dstId = string(payload, DESTINATION, null);
if (srcId != null && dstId != null) {
HostId sHostId = hostId(srcId);
HostId dHostId = hostId(dstId);
Host sHost = hostService.getHost(sHostId);
Host dHost = hostService.getHost(dHostId);
if (sHost != null && dHost != null) {
ArrayNode ipProtos = arrayNode();
ArrayNode types = arrayNode();
String sHostName = ipForHost(sHost);
String dHostName = ipForHost(dHost);
for (String proto : IP_PROTOCOL_ARRAY) {
ipProtos.add(proto);
}
for (String type : VTAP_TYPE_ARRAY) {
types.add(type);
}
payload.put(SOURCE_HOST_NAME, sHostName);
payload.put(DESTINATION_HOST_NAME, dHostName);
payload.put(IP_PROTOCOL_LIST, ipProtos);
payload.put(VTAP_TYPE_LIST, types);
sendMessage(OSV_IS_ACTIVATED_RESP, payload);
}
}
}
// Returns the first of the given host's set of IP addresses as a string.
private String ipForHost(Host host) {
Set<IpAddress> ipAddresses = host.ipAddresses();
Iterator<IpAddress> it = ipAddresses.iterator();
return it.hasNext() ? it.next().toString() + "/32" : "unknown";
}
}
private final class VtapCreateRequestHandler extends RequestHandler {
private String srcIp;
private String dstIp;
private String ipProto;
private String srcTpPort;
private String dstTpPort;
private String vtapTypeStr;
private ObjectNode result = objectNode();
private VtapCreateRequestHandler() {
super(OSV_CREATE_REQ);
}
@Override
public void process(ObjectNode payload) {
srcIp = string(payload, SOURCE_IP, null);
dstIp = string(payload, DESTINATION_IP, null);
ipProto = string(payload, IP_PROTOCOL, null);
srcTpPort = string(payload, SOURCE_TRANSPORT_PORT, null);
dstTpPort = string(payload, DESTINATION_TRANSPORT_PORT, null);
vtapTypeStr = string(payload, VTAP_TYPE, null);
log.trace("VtapCreateRequestHandler payload srcIp:{}, dstIp:{}, ipPro:{}, " +
"srcTpPort:{}, dstTpPort:{}, vtapType:{}", srcIp, dstIp, ipProto,
srcTpPort, dstTpPort, vtapTypeStr);
DefaultOpenstackVtapCriterion.Builder vtapCriterionBuilder = DefaultOpenstackVtapCriterion.builder();
if (makeCriterion(vtapCriterionBuilder)) {
OpenstackVtap.Type type = getVtapTypeFromString(vtapTypeStr.toLowerCase());
if (type == null) {
log.warn(INVALID_VTAP_TYPE);
result.put(RESULT, FAILED);
result.put(VALUE, INVALID_VTAP_TYPE);
sendMessage(OSV_CREATE_RESP, result);
return;
}
OpenstackVtap vtap = vtapService.createVtap(type, vtapCriterionBuilder.build());
if (vtap != null) {
log.info("Created OpenstackVtap with id {}", vtap.id().toString());
result.put(RESULT, SUCCESS);
result.put(VALUE, "vtap id: " + vtap.id().toString());
} else {
log.warn(FAILED_TO_CREATE_VTAP);
result.put(RESULT, FAILED);
result.put(VALUE, FAILED_TO_CREATE_VTAP);
}
}
sendMessage(OSV_CREATE_RESP, result);
}
private boolean makeCriterion(DefaultOpenstackVtapCriterion.Builder vtapCriterionBuilder) {
try {
vtapCriterionBuilder.srcIpPrefix(IpPrefix.valueOf(srcIp));
vtapCriterionBuilder.dstIpPrefix(IpPrefix.valueOf(dstIp));
} catch (Exception e) {
log.warn(WRONG_IP_ADDRESS);
result.put(RESULT, FAILED);
result.put(VALUE, WRONG_IP_ADDRESS);
return false;
}
vtapCriterionBuilder.ipProtocol(getProtocolTypeFromString(ipProto.toLowerCase()));
try {
vtapCriterionBuilder.srcTpPort(TpPort.tpPort(Integer.valueOf(srcTpPort)));
vtapCriterionBuilder.dstTpPort(TpPort.tpPort(Integer.valueOf(dstTpPort)));
} catch (Exception e) {
log.warn(INVALID_TRANSPORT_PORT);
result.put(RESULT, FAILED);
result.put(VALUE, INVALID_TRANSPORT_PORT);
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Web GUI for the control plane manager.
*/
package org.onosproject.openstackvtap.gui;

View File

@ -15,9 +15,7 @@
*/
package org.onosproject.openstackvtap.impl;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.onosproject.net.AbstractDescription;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DeviceId;
@ -26,33 +24,47 @@ import org.onosproject.openstackvtap.api.OpenstackVtap;
import org.onosproject.openstackvtap.api.OpenstackVtapCriterion;
import org.onosproject.openstackvtap.api.OpenstackVtapId;
import java.util.Objects;
import java.util.Set;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Default implementation of an immutable openstack vTap.
* Default implementation of an immutable OpenstackVtap.
*/
public final class DefaultOpenstackVtap extends AbstractDescription implements OpenstackVtap {
private final OpenstackVtapId id;
private final Type type;
private final OpenstackVtapCriterion vTapCriterion;
private final OpenstackVtapCriterion vtapCriterion;
private final Set<DeviceId> txDeviceIds;
private final Set<DeviceId> rxDeviceIds;
// private constructor not intended to use from external
private DefaultOpenstackVtap(OpenstackVtapId id, Type type,
OpenstackVtapCriterion vTapCriterion,
Set<DeviceId> txDeviceIds, Set<DeviceId> rxDeviceIds,
/**
* Creates an DefaultOpenstackVtap using the supplied information.
*
* @param id vtap identifier
* @param type type of vtap (all,rx,tx)
* @param vtapCriterion criterion of vtap
* @param txDeviceIds device identifiers applied by vtap tx
* @param rxDeviceIds device identifiers applied by vtap rx
* @param annotations optional key/value annotations
*/
private DefaultOpenstackVtap(OpenstackVtapId id,
Type type,
OpenstackVtapCriterion vtapCriterion,
Set<DeviceId> txDeviceIds,
Set<DeviceId> rxDeviceIds,
SparseAnnotations... annotations) {
super(annotations);
this.id = id;
this.type = type;
this.vTapCriterion = vTapCriterion;
this.txDeviceIds = txDeviceIds;
this.rxDeviceIds = rxDeviceIds;
this.id = checkNotNull(id);
this.type = checkNotNull(type);
this.vtapCriterion = checkNotNull(vtapCriterion);
this.txDeviceIds = Objects.nonNull(txDeviceIds) ?
ImmutableSet.copyOf(txDeviceIds) : ImmutableSet.of();
this.rxDeviceIds = Objects.nonNull(rxDeviceIds) ?
ImmutableSet.copyOf(rxDeviceIds) : ImmutableSet.of();
}
@Override
@ -66,129 +78,184 @@ public final class DefaultOpenstackVtap extends AbstractDescription implements O
}
@Override
public OpenstackVtapCriterion vTapCriterion() {
return vTapCriterion;
public OpenstackVtapCriterion vtapCriterion() {
return vtapCriterion;
}
@Override
public Set<DeviceId> txDeviceIds() {
return ImmutableSet.copyOf(txDeviceIds);
return txDeviceIds;
}
@Override
public Set<DeviceId> rxDeviceIds() {
return ImmutableSet.copyOf(rxDeviceIds);
return rxDeviceIds;
}
@Override
public int hashCode() {
return Objects.hash(id, type, vtapCriterion, txDeviceIds, rxDeviceIds);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof DefaultOpenstackVtap) {
final DefaultOpenstackVtap other = (DefaultOpenstackVtap) obj;
return Objects.equals(this.id, other.id) &&
Objects.equals(this.type, other.type) &&
Objects.equals(this.vtapCriterion, other.vtapCriterion) &&
Objects.equals(this.txDeviceIds(), other.txDeviceIds()) &&
Objects.equals(this.rxDeviceIds(), other.rxDeviceIds()) &&
Objects.equals(this.annotations(), other.annotations());
}
return false;
}
@Override
public String toString() {
return toStringHelper(this)
.add("id", id)
.add("type", type)
.add("vTapCriterion", vTapCriterion)
.add("txDeviceIds", txDeviceIds)
.add("rxDeviceIds", rxDeviceIds)
.add("id", id())
.add("type", type())
.add("vtapCriterion", vtapCriterion())
.add("txDeviceIds", txDeviceIds())
.add("rxDeviceIds", rxDeviceIds())
.add("annotations", annotations())
.toString();
}
@Override
public int hashCode() {
return Objects.hashCode(id, type, vTapCriterion, txDeviceIds, rxDeviceIds);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DefaultOpenstackVtap that = (DefaultOpenstackVtap) o;
return Objects.equal(this.id, that.id)
&& Objects.equal(this.type, that.type)
&& Objects.equal(this.vTapCriterion, that.vTapCriterion)
&& Objects.equal(this.txDeviceIds, that.txDeviceIds)
&& Objects.equal(this.rxDeviceIds, that.rxDeviceIds);
}
/**
* Creates a new default openstack vTap builder.
* Creates OpenstackVtap builder with default parameters.
*
* @return default openstack vTap builder
* @return builder
*/
public static Builder builder() {
return new Builder();
}
/**
* Creates OpenstackVtap builder inheriting with default parameters,
* from specified OpenstackVtap.
*
* @param vtap to inherit default from
* @return builder
*/
public static Builder builder(OpenstackVtap vtap) {
return new Builder(vtap);
}
/**
* Builder for DefaultOpenstackVtap object.
*/
public static class Builder implements OpenstackVtap.Builder {
private static final SparseAnnotations EMPTY = DefaultAnnotations.builder().build();
private OpenstackVtapId id;
private Type type;
private OpenstackVtapCriterion vTapCriterion;
private Type type = Type.VTAP_ALL;
private OpenstackVtapCriterion vtapCriterion;
private Set<DeviceId> txDeviceIds;
private Set<DeviceId> rxDeviceIds;
private SparseAnnotations annotations = EMPTY;
private SparseAnnotations annotations = DefaultAnnotations.EMPTY;
// private constructor not intended to use from external
// Private constructor not intended to use from external
Builder() {
}
Builder(OpenstackVtap description) {
this.id = description.id();
this.type = description.type();
this.vtapCriterion = description.vtapCriterion();
this.type = description.type();
this.txDeviceIds = description.txDeviceIds();
this.rxDeviceIds = description.rxDeviceIds();
this.annotations = (SparseAnnotations) description.annotations();
}
/**
* Sets mandatory field id.
*
* @param id to set
* @return self
*/
@Override
public Builder id(OpenstackVtapId id) {
this.id = id;
return this;
}
/**
* Sets mandatory field type.
*
* @param type of the vtap
* @return self
*/
@Override
public Builder type(Type type) {
this.type = type;
return this;
}
/**
* Sets mandatory field criterion.
*
* @param vtapCriterion for the vtap
* @return self
*/
@Override
public Builder vTapCriterion(OpenstackVtapCriterion vTapCriterion) {
this.vTapCriterion = vTapCriterion;
public Builder vtapCriterion(OpenstackVtapCriterion vtapCriterion) {
this.vtapCriterion = vtapCriterion;
return this;
}
/**
* Sets a tx deviceId set.
*
* @param txDeviceIds deviceId set for tx
* @return builder
*/
@Override
public Builder txDeviceIds(Set<DeviceId> txDeviceIds) {
if (txDeviceIds != null) {
this.txDeviceIds = ImmutableSet.copyOf(txDeviceIds);
} else {
this.txDeviceIds = Sets.newHashSet();
}
this.txDeviceIds = txDeviceIds;
return this;
}
/**
* Sets a rx deviceId set.
*
* @param rxDeviceIds deviceId set for rx
* @return builder
*/
@Override
public Builder rxDeviceIds(Set<DeviceId> rxDeviceIds) {
if (rxDeviceIds != null) {
this.rxDeviceIds = ImmutableSet.copyOf(rxDeviceIds);
} else {
this.rxDeviceIds = Sets.newHashSet();
}
this.rxDeviceIds = rxDeviceIds;
return this;
}
/**
* Sets annotations.
*
* @param annotations of the vtap
* @return self
*/
@Override
public Builder annotations(SparseAnnotations... annotations) {
checkArgument(annotations.length <= 1,
"Only one set of annotations is expected");
this.annotations = annotations.length == 1 ? annotations[0] : EMPTY;
public Builder annotations(SparseAnnotations annotations) {
this.annotations = annotations;
return this;
}
/**
* Builds a DefaultOpenstackVtap instance.
*
* @return DefaultOpenstackVtap
*/
@Override
public DefaultOpenstackVtap build() {
return new DefaultOpenstackVtap(id, type, vTapCriterion,
txDeviceIds, rxDeviceIds, annotations);
return new DefaultOpenstackVtap(checkNotNull(id),
checkNotNull(type),
checkNotNull(vtapCriterion),
txDeviceIds,
rxDeviceIds,
checkNotNull(annotations));
}
}

View File

@ -24,16 +24,15 @@ import org.onosproject.openstackvtap.api.OpenstackVtapCriterion;
import static com.google.common.base.Preconditions.checkArgument;
/**
* Default implementation of an immutable openstack vTap criterion.
* Default implementation of an immutable openstack vtap criterion.
*/
public final class DefaultOpenstackVtapCriterion implements OpenstackVtapCriterion {
private final IpPrefix srcIpPrefix;
private final IpPrefix dstIpPrefix;
private final byte ipProtocol;
private final byte ipProtocol;
private final TpPort srcTpPort;
private final TpPort dstTpPort;
private static final String NOT_NULL_MSG = "Element % cannot be null";
private final TpPort dstTpPort;
// private constructor not intended to use from external
private DefaultOpenstackVtapCriterion(IpPrefix srcIpPrefix,
@ -107,18 +106,20 @@ public final class DefaultOpenstackVtapCriterion implements OpenstackVtapCriteri
}
/**
* Creates a new default openstack vTap criterion builder.
* Creates a new default openstack vtap criterion builder.
*
* @return default openstack vTap criterion builder
* @return default openstack vtap criterion builder
*/
public static Builder builder() {
return new Builder();
}
/**
* A builder class for openstack vTap criterion builder.
* A builder class for openstack vtap criterion builder.
*/
public static final class Builder implements OpenstackVtapCriterion.Builder {
private static final String NOT_NULL_MSG = "OpenstackVtapCriterion % cannot be null";
private IpPrefix srcIpPrefix;
private IpPrefix dstIpPrefix;
private byte ipProtocol;
@ -168,4 +169,5 @@ public final class DefaultOpenstackVtapCriterion implements OpenstackVtapCriteri
return this;
}
}
}

View File

@ -0,0 +1,203 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openstackvtap.impl;
import org.onlab.packet.IpAddress;
import org.onosproject.net.AbstractDescription;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Default implementation of an immutable OpenstackVtapNetwork.
*/
public class DefaultOpenstackVtapNetwork extends AbstractDescription implements OpenstackVtapNetwork {
private final Mode mode;
private final Integer networkId;
private final IpAddress serverIp;
/**
* Creates an DefaultOpenstackVtapNetwork using the supplied information.
*
* @param mode mode of vtap network
* @param networkId network id of the vtap tunneling network
* @param serverIp server IP address used for tunneling
* @param annotations optional key/value annotations
*/
protected DefaultOpenstackVtapNetwork(Mode mode,
Integer networkId,
IpAddress serverIp,
SparseAnnotations... annotations) {
super(annotations);
this.mode = checkNotNull(mode);
this.networkId = networkId;
this.serverIp = checkNotNull(serverIp);
}
@Override
public Mode mode() {
return mode;
}
@Override
public Integer networkId() {
return networkId;
}
@Override
public IpAddress serverIp() {
return serverIp;
}
@Override
public int hashCode() {
return Objects.hash(mode, networkId, serverIp);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof DefaultOpenstackVtapNetwork) {
final DefaultOpenstackVtapNetwork other = (DefaultOpenstackVtapNetwork) obj;
return Objects.equals(this.mode, other.mode) &&
Objects.equals(this.networkId, other.networkId) &&
Objects.equals(this.serverIp, other.serverIp) &&
Objects.equals(this.annotations(), other.annotations());
}
return false;
}
@Override
public String toString() {
return toStringHelper(this)
.add("mode", mode())
.add("networkId", networkId())
.add("serverIp", serverIp())
.add("annotations", annotations())
.toString();
}
/**
* Creates OpenstackVtapNetwork builder with default parameters.
*
* @return builder
*/
public static Builder builder() {
return new Builder();
}
/**
* Creates OpenstackVtapNetwork builder inheriting with default parameters,
* from specified OpenstackVtapNetwork.
*
* @param vtapNetwork to inherit default from
* @return builder
*/
public static Builder builder(OpenstackVtapNetwork vtapNetwork) {
return new Builder(vtapNetwork);
}
/**
* Builder for DefaultOpenstackVtapNetwork object.
*/
public static class Builder implements OpenstackVtapNetwork.Builder {
private Mode mode;
private Integer networkId;
private IpAddress serverIp;
private SparseAnnotations annotations = DefaultAnnotations.EMPTY;
// private constructor not intended to use from external
private Builder() {
}
Builder(OpenstackVtapNetwork description) {
this.mode = description.mode();
this.networkId = description.networkId();
this.serverIp = description.serverIp();
this.annotations = (SparseAnnotations) description.annotations();
}
/**
* Sets mandatory field mode.
*
* @param mode of vtap network
* @return self
*/
@Override
public Builder mode(Mode mode) {
this.mode = mode;
return this;
}
/**
* Sets mandatory field networkId.
*
* @param networkId of the vtap tunneling network
* @return self
*/
@Override
public Builder networkId(Integer networkId) {
this.networkId = networkId;
return this;
}
/**
* Sets mandatory field serverIp.
*
* @param serverIp address used for tunneling
* @return self
*/
@Override
public Builder serverIp(IpAddress serverIp) {
this.serverIp = serverIp;
return this;
}
/**
* Sets annotations.
*
* @param annotations of the vtap network
* @return self
*/
@Override
public Builder annotations(SparseAnnotations annotations) {
this.annotations = annotations;
return this;
}
/**
* Builds a DefaultOpenstackVtapNetwork instance.
*
* @return DefaultOpenstackVtapNetwork
*/
@Override
public DefaultOpenstackVtapNetwork build() {
return new DefaultOpenstackVtapNetwork(checkNotNull(mode),
networkId,
checkNotNull(serverIp),
checkNotNull(annotations));
}
}
}

View File

@ -15,6 +15,6 @@
*/
/**
* Implementation for Openstack vtap.
* Implementation for openstack vtap.
*/
package org.onosproject.openstackvtap.impl;

View File

@ -16,15 +16,31 @@
package org.onosproject.openstackvtap.util;
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onosproject.net.Host;
import org.onosproject.net.behaviour.TunnelDescription;
import org.onosproject.net.group.DefaultGroupKey;
import org.onosproject.net.group.GroupKey;
import org.onosproject.openstackvtap.api.OpenstackVtap;
import org.onosproject.openstackvtap.api.OpenstackVtapCriterion;
import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
import org.slf4j.Logger;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_NETWORK_ID;
import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_PORT_ID;
/**
* An utility that used in openstack vTap app.
* An utilities that used in openstack vtap app.
*/
public final class OpenstackVtapUtil {
private static final String VTAP_TUNNEL_GRE = "vtap_gre";
private static final String VTAP_TUNNEL_VXLAN = "vtap_vxlan";
private static final String VTAP_GROUP_KEY = "VTAP_GROUP_KEY";
/**
@ -33,32 +49,11 @@ public final class OpenstackVtapUtil {
private OpenstackVtapUtil() {
}
/**
* Obtains vTap type from the given string.
*
* @param str string
* @return vTap type
*/
public static OpenstackVtap.Type getVtapTypeFromString(String str) {
switch (str) {
case "all":
return OpenstackVtap.Type.VTAP_ALL;
case "tx":
return OpenstackVtap.Type.VTAP_TX;
case "rx":
return OpenstackVtap.Type.VTAP_RX;
case "none":
return OpenstackVtap.Type.VTAP_NONE;
default:
throw new IllegalArgumentException("Invalid vTap type string");
}
}
/**
* Obtains IP protocol type from the given string.
*
* @param str string
* @return vTap type
* @param str protocol string
* @return IP protocol number
*/
public static byte getProtocolTypeFromString(String str) {
switch (str) {
@ -68,12 +63,132 @@ public final class OpenstackVtapUtil {
return IPv4.PROTOCOL_UDP;
case "icmp":
return IPv4.PROTOCOL_ICMP;
default:
case "any":
return 0;
default:
throw new IllegalArgumentException("Invalid vtap protocol string");
}
}
/**
* Obtains openstack vtap type from the given string.
*
* @param str vtap type string
* @return vtap type
*/
public static OpenstackVtap.Type getVtapTypeFromString(String str) {
switch (str) {
case "all":
return OpenstackVtap.Type.VTAP_ALL;
case "rx":
return OpenstackVtap.Type.VTAP_RX;
case "tx":
return OpenstackVtap.Type.VTAP_TX;
case "any":
return OpenstackVtap.Type.VTAP_ANY;
default:
throw new IllegalArgumentException("Invalid vtap type string");
}
}
/**
* Checks whether the given IP address is included in vtap criterion with
* TX and RX directions by given vtap type.
*
* @param type vtap type
* @param criterion vtap criterion
* @param ip IP address to check
* @return true on match address, false otherwise
*/
public static boolean containsIp(OpenstackVtap.Type type, OpenstackVtapCriterion criterion, IpAddress ip) {
boolean isTxEdge = type.isValid(OpenstackVtap.Type.VTAP_TX) &&
criterion.srcIpPrefix().contains(ip);
boolean isRxEdge = type.isValid(OpenstackVtap.Type.VTAP_RX) &&
criterion.dstIpPrefix().contains(ip);
return isTxEdge || isRxEdge;
}
/**
* Checks the host validation from annotation information.
*
* @param host host to check
* @return true on validate, false otherwise
*/
public static boolean isValidHost(Host host) {
return !host.ipAddresses().isEmpty() &&
host.annotations().value(ANNOTATION_NETWORK_ID) != null &&
host.annotations().value(ANNOTATION_PORT_ID) != null;
}
/**
* Checks whether the given IP prefix is contained in the first host rather
* than in the second host.
*
* @param host1 first host instance
* @param host2 second host instance
* @param ipPrefix IP prefix to be looked up
* @return a negative integer, zero, or a positive integer as the
* first argument is less than, equal to, or greater than the
* second.
*/
public static int hostCompareIp(Host host1, Host host2, IpPrefix ipPrefix) {
if ((host1 == null || host1.ipAddresses().stream().noneMatch(ipPrefix::contains)) &&
(host2 != null || host2.ipAddresses().stream().anyMatch(ipPrefix::contains))) {
return -1;
} else if ((host1 != null && host1.ipAddresses().stream().anyMatch(ipPrefix::contains)) &&
(host2 == null || host2.ipAddresses().stream().noneMatch(ipPrefix::contains))) {
return 1;
}
return 0;
}
/**
* Obtains flow group key from the given id.
*
* @param groupId flow group identifier
* @return flow group key
*/
public static GroupKey getGroupKey(int groupId) {
return new DefaultGroupKey((VTAP_GROUP_KEY + Integer.toString(groupId)).getBytes());
}
/**
* Obtains tunnel interface name from the given openstack vtap network mode.
*
* @param mode vtap network mode
* @return tunnel interface name
*/
public static String getTunnelName(OpenstackVtapNetwork.Mode mode) {
switch (mode) {
case GRE:
return VTAP_TUNNEL_GRE;
case VXLAN:
return VTAP_TUNNEL_VXLAN;
default:
return null;
}
}
/**
* Obtains tunnel description type from the given openstack vtap network mode.
*
* @param mode vtap network mode
* @return tunnel description type
*/
public static TunnelDescription.Type getTunnelType(OpenstackVtapNetwork.Mode mode) {
return TunnelDescription.Type.valueOf(mode.toString());
}
/**
* Print stack trace of given exception.
*
* @param log logger for using print
* @param e exception to print
*/
public static void dumpStackTrace(Logger log, Exception e) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(outputStream));
log.error("\n{}", new String(outputStream.toByteArray(), StandardCharsets.UTF_8));
}
}

View File

@ -15,6 +15,6 @@
*/
/**
* Openstack vTap utility package.
* Utility package that used in openstack vtap app.
*/
package org.onosproject.openstackvtap.util;

View File

@ -0,0 +1,53 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openstackvtap.web;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.codec.CodecService;
import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
import org.onosproject.openstackvtap.codec.OpenstackVtapNetworkCodec;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Implementation of the JSON codec brokering service for openstack vtap network.
*/
@Component(immediate = true)
public class OpenstackVtapNetworkCodecRegister {
private final org.slf4j.Logger log = getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CodecService codecService;
@Activate
protected void activate() {
codecService.registerCodec(OpenstackVtapNetwork.class, new OpenstackVtapNetworkCodec());
log.info("Started");
}
@Deactivate
protected void deactivate() {
codecService.unregisterCodec(OpenstackVtapNetwork.class);
log.info("Stopped");
}
}

View File

@ -0,0 +1,165 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.openstackvtap.web;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.openstackvtap.api.OpenstackVtapAdminService;
import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
import org.onosproject.rest.AbstractWebResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
import static org.onlab.util.Tools.readTreeFromStream;
/**
* Handles REST API call of openstack vtap network.
*/
@Path("vtap-network")
public class OpenstackVtapNetworkWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(getClass());
private static final String MESSAGE_NETWORK = "Received openstackVtapNetwork {} request";
private static final String ERROR_DUPLICATE = "Already has data {}";
private static final String ERROR_NOTFOUND = "No data to update {}";
private static final String CREATE = "CREATE";
private static final String READ = "READ";
private static final String UPDATE = "UPDATE";
private static final String DELETE = "DELETE";
private static final String NETWORK = "network";
private final OpenstackVtapAdminService vtapAdminService = get(OpenstackVtapAdminService.class);
/**
* Creates a openstack vtap network from the JSON input stream.
*
* @param input openstack vtap network JSON input stream
* @return 200 OK if the JSON is correct
* 400 BAD_REQUEST if the JSON is malformed
* 409 CONFLICT if already the vtap network exists
* @onos.rsModel OpenstackVtapNetwork
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response createNetwork(InputStream input) {
log.info(MESSAGE_NETWORK, CREATE);
OpenstackVtapNetwork vtapNetwork = readNetworkConfiguration(input);
if (vtapNetwork == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
if (vtapAdminService.createVtapNetwork(vtapNetwork.mode(),
vtapNetwork.networkId(), vtapNetwork.serverIp()) == null) {
log.warn(ERROR_DUPLICATE, vtapNetwork);
return Response.status(Response.Status.CONFLICT).build();
}
return Response.ok().build();
}
/**
* Updates openstack vtap network from the JSON input stream.
*
* @param input openstack vtap network JSON input stream
* @return 200 OK if the JSON is correct
* 400 BAD_REQUEST if the JSON is malformed
* 404 NOT_FOUND if vtap network is not exists
* @onos.rsModel OpenstackVtapNetwork
*/
@PUT
@Consumes(MediaType.APPLICATION_JSON)
public Response updateNetwork(InputStream input) {
log.info(MESSAGE_NETWORK, UPDATE);
OpenstackVtapNetwork vtapNetwork = readNetworkConfiguration(input);
if (vtapNetwork == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
if (vtapAdminService.updateVtapNetwork(vtapNetwork) == null) {
log.warn(ERROR_NOTFOUND, vtapNetwork);
return Response.status(Response.Status.NOT_FOUND).build();
}
return Response.ok().build();
}
/**
* Get openstack vtap network.
*
* @return 200 OK with openstack vtap network
* 404 NOT_FOUND if openstackvtap network is not exists
* @onos.rsModel OpenstackVtapNetwork
*/
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getNetwork() {
log.info(MESSAGE_NETWORK, READ);
OpenstackVtapNetwork vtapNetwork = vtapAdminService.getVtapNetwork();
if (vtapNetwork == null) {
return Response.status(Response.Status.NOT_FOUND).build();
}
JsonNode jsonNode = codec(OpenstackVtapNetwork.class).encode(vtapNetwork, this);
return Response.ok(jsonNode, MediaType.APPLICATION_JSON_TYPE).build();
}
/**
* Removes openstack network.
*
* @return 200 OK on removing success
* 404 NOT_FOUND if openstackvtap network is not exists
* @onos.rsModel OpenstackVtapNetwork
*/
@DELETE
@Consumes(MediaType.APPLICATION_JSON)
public Response deleteNetwork() {
log.info(MESSAGE_NETWORK, DELETE);
if (vtapAdminService.removeVtapNetwork() == null) {
return Response.status(Response.Status.NOT_FOUND).build();
}
return Response.ok().build();
}
private OpenstackVtapNetwork readNetworkConfiguration(InputStream input) {
try {
JsonNode jsonTree = readTreeFromStream(mapper().enable(INDENT_OUTPUT), input);
ObjectNode vtap = (ObjectNode) jsonTree.get(NETWORK);
return codec(OpenstackVtapNetwork.class).decode(vtap, this);
} catch (Exception e) {
log.error(e.toString());
return null;
}
}
}

View File

@ -20,11 +20,12 @@ import org.onlab.rest.AbstractWebApplication;
import java.util.Set;
/**
* Openstack vTap REST APIs web application.
* Openstack vtap REST APIs web application.
*/
public class OpenstackVtapWebApplication extends AbstractWebApplication {
@Override
public Set<Class<?>> getClasses() {
return getClasses(OpenstackVtapWebResource.class);
return getClasses(OpenstackVtapWebResource.class,
OpenstackVtapNetworkWebResource.class);
}
}

View File

@ -36,8 +36,6 @@ public class OpenstackVtapWebResource extends AbstractWebResource {
* OpenstackVtapServiceImpl method.
*
* @return 200 OK
*
* @onos.rsModel dummy
*/
@GET
@Produces(MediaType.APPLICATION_JSON)

View File

@ -42,7 +42,7 @@
</command>
<command>
<action class="org.onosproject.openstackvtap.cli.OpenstackVtapOutputCommand" />
<action class="org.onosproject.openstackvtap.cli.OpenstackVtapNetworkListCommand" />
</command>
</command-bundle>

View File

@ -0,0 +1,50 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
ONOS GUI -- OpenstackVtap -- CSS file
*/
/* --- Topo Vtap Panel --- */
#topo-p-vtap {
padding: 16px;
top: 190px;
left: 20px;
}
.topo-p td input.number-input {
width: 50px;
}
.topo-p div.footer tbody {
float: right;
}
.topo-p div.footer tbody input.button-input {
background-color: #5b99d2;
border: 0;
border-radius: 3px;
color: #fff;
height: 25px;
width: 60px;
padding: 1px 0 0 0;
}
#vtap-dialog {
padding: 16px;
top: 190px;
left: 20px;
}

View File

@ -0,0 +1,4 @@
<!-- partial HTML -->
<div id="ov-openstackvtap">
<p>This is a hidden view .. just a placeholder to house the javascript</p>
</div>

View File

@ -0,0 +1,406 @@
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
ONOS GUI -- Openstack Vtap View Module
*/
(function () {
'use strict';
// injected refs
var $log, tov, ovts, fs, wss, tts, api, gs, ps, ds;
// constants
var pCls = 'topo-p',
idVta = 'topo-p-vtap',
idVDi = 'vtap-dialog',
vtapPanelOpts = {
edge: 'left',
width: 330, // vtap panel width
}
// panels
var vtap;
// selected info
var selectedItem;
// constants
var osvIsActReq = 'openstackVtapIsActivatedRequest',
osvIsActResp = 'openstackVtapIsActivatedResponse',
osvCreateReq = 'openstackVtapCreateRequest',
osvCreateResp = 'openstackVtapCreateResponse';
// function to be replaced by the localization bundle function
var topoLion = function (x) {
return '#ttrafov#' + x + '#';
};
var overlay = {
overlayId: 'vtap-overlay',
glyphId: 'm_details',
tooltip: 'Openstack Vtap Overlay',
activate: function () {
$log.debug("Openstack Vtap topology overlay ACTIVATED");
},
deactivate: function () {
destroyVtapPanel();
$log.debug("Openstack Vtap topology overlay DEACTIVATED");
},
// detail panel button definitions
buttons: {
createHostVtapBtn: {
gid: 'm_details',
tt: 'Create Host-to-Host Vtap',
cb: displayVtap
},
showRelatedTraffic: {
gid: 'm_relatedIntents',
tt: function () { return topoLion('tr_btn_show_related_traffic'); },
cb: function (data) { tts.showRelatedIntents(); },
},
},
hooks: {
multi: function (selectOrder) {
var selectedHost = new Object();
for (var index in selectOrder) {
if (index == 0) {
selectedHost.src = selectOrder[index];
} else if (index == 1) {
selectedHost.dst = selectOrder[index];
}
}
selectedItem = selectedHost;
tov.addDetailButton('showRelatedTraffic');
if(selectOrder.length == 2) {
tov.addDetailButton('createHostVtapBtn');
}
}
}
};
// Panel API
function createTopoPanel(id, opts) {
var p = ps.createPanel(id, opts),
pid = id,
header, body, footer;
p.classed(pCls, true);
function panel() {
return p;
}
function hAppend(x) {
return header.append(x);
}
function bAppend(x) {
return body.append(x);
}
function fAppend(x) {
return footer.append(x);
}
function setup() {
p.empty();
p.append('div').classed('header', true);
p.append('div').classed('body', true);
p.append('div').classed('footer', true);
header = p.el().select('.header');
body = p.el().select('.body');
footer = p.el().select('.footer');
}
function destroy() {
ps.destroyPanel(pid);
}
return {
panel: panel,
setup: setup,
destroy: destroy,
appendHeader: hAppend,
appendBody: bAppend,
appendFooter: fAppend,
};
}
function hideVtapPanel() {
vtap.panel().hide();
}
function destroyVtapPanel() {
if(vtap != null) {
vtap.destroy();
}
vtap = null;
}
function addInput(tbody, type, id, label, value) {
var tr = tbody.append('tr'),
lab;
if (typeof label === 'string') {
lab = label.replace(/_/g, ' ');
} else {
lab = label;
}
tr.append('td').attr('class', 'label').text(lab + ' :');
if (type == 'radio') {
var td = tr.append('td');
for(var index in value) {
if(index == 0) {
td.append('input').classed( type + '-input', true)
.attr('type', type)
.attr('value', value[index])
.attr('name', label)
.attr('id', id)
.attr('checked', 'true');
} else {
td.append('input').classed( type + '-input', true)
.attr('type', type)
.attr('name', label)
.attr('id', id)
.attr('value', value[index]);
}
td.append('span').text(value[index]);
}
} else {
tr.append('td').append('input').classed(type + '-input', true).attr('type', type)
.attr('id', id).attr('value', value);
}
}
function addButton(tr, callback, value) {
tr.append('td').append('input').classed('button-input', true).attr('type', 'button')
.attr('value', value).on('click', callback);
}
function makeButton(callback, text, keyName) {
var cb = fs.isF(callback),
key = fs.isS(keyName);
function invoke() {
cb && cb();
}
return createDiv('vtap-button')
.text(text)
.on('click', invoke);
}
function createDiv(cls) {
var div = d3.select(document.createElement('div'));
if (cls) {
div.classed(cls, true);
}
return div;
}
function addInput(tbody, type, id, label, value) {
var tr = tbody.append('tr'),
lab;
if (typeof label === 'string') {
lab = label.replace(/_/g, ' ');
} else {
lab = label;
}
tr.append('td').attr('class', 'label').text(lab + ' :');
if (type == 'radio') {
var td = tr.append('td');
for(var index in value) {
if(index == 0) {
td.append('input').classed( type + '-input', true)
.attr('type', type)
.attr('value', value[index])
.attr('name', label)
.attr('id', id)
.attr('checked', 'true');
} else {
td.append('input').classed( type + '-input', true)
.attr('type', type)
.attr('name', label)
.attr('id', id)
.attr('value', value[index]);
}
td.append('span').text(value[index]);
}
} else {
tr.append('td').append('input').classed(type + '-input', true).attr('type', type)
.attr('id', id).attr('value', value);
}
}
function addButton(tr, callback, value) {
tr.append('td').append('input').classed('button-input', true).attr('type', 'button')
.attr('value', value).on('click', callback);
}
function makeButton(callback, text, keyName) {
var cb = fs.isF(callback),
key = fs.isS(keyName);
function invoke() {
cb && cb();
}
return createDiv('vtap-button')
.text(text)
.on('click', invoke);
}
function createDiv(cls) {
var div = d3.select(document.createElement('div'));
if (cls) {
div.classed(cls, true);
}
return div;
}
function displayVtap() {
$log.debug("sendEvent openstackVtapIsActivatedRequest: ", selectedItem);
wss.sendEvent(osvIsActReq, selectedItem);
}
function respIsActCb(selected) {
$log.debug("openstackVtapIsActivatedResponse: ", selected);
if(vtap == null) {
vtap = createTopoPanel(idVta, vtapPanelOpts);
}
vtap.setup();
var svg = vtap.appendHeader('div')
.classed('icon', true)
.append('svg'),
title = vtap.appendHeader('h2'),
table = vtap.appendBody('table'),
tbody = table.append('tbody'),
glyphId = 'm_details';
gs.addGlyph(svg, glyphId, 30, 0, [1, 1]);
title.text('Create OpenstackVtap');
addInput(tbody, 'text', 'srcIp', 'Source IP', selected.srcName);
addInput(tbody, 'text', 'dstIp', 'Destination IP', selected.dstName);
addInput(tbody, 'radio', 'ipProto', 'Protocol', selected.ipProtoList);
addInput(tbody, 'number', 'srcPort', 'Source Port', "");
addInput(tbody, 'number', 'dstPort', 'Destination Port', "");
addInput(tbody, 'radio', 'vtapType', 'Type', selected.vtapTypeList);
vtap.appendFooter('hr');
var footTr = vtap.appendFooter('table').append('tbody').append('tr');
addButton(footTr, createVtap, 'Create');
addButton(footTr, hideVtapPanel, 'Cancel');
vtap.panel().show();
}
function createVtap() {
var vtapInfo = {};
vtapInfo.srcIp = document.getElementById('srcIp').value;
vtapInfo.dstIp = document.getElementById('dstIp').value;
vtapInfo.ipProto = document.querySelector('input[name="Protocol"]:checked').value;
vtapInfo.srcPort = document.getElementById('srcPort').value;
vtapInfo.dstPort = document.getElementById('dstPort').value;
vtapInfo.vtapType = document.querySelector('input[name="Type"]:checked').value;
if(vtapInfo.srcPort == ""){
vtapInfo.srcPort = 0;
}
if(vtapInfo.dstPort == ""){
vtapInfo.dstPort = 0;
}
$log.debug("sendEvent openstackVtapCreateRequest: ", vtapInfo);
wss.sendEvent(osvCreateReq, vtapInfo);
hideVtapPanel();
}
function respCreateCb(result) {
$log.debug("respCreateCb: ", result);
function dOK() {
if(result.result == "Failed"){
displayVtap(selectedItem);
} else {
destroyVtapPanel();
}
}
function createContent(value) {
var content = ds.createDiv();
content.append('p').text(value);
return content;
}
ds.openDialog(idVDi, vtapPanelOpts)
.setTitle("Create Vtap " + result.result)
.addContent(createContent(result.value))
.addOk(dOK);
}
// invoke code to register with the overlay service
angular.module('ovOpenstackvtap', [])
.factory('OpenstackVtapTopovService',
['$log', 'FnService', 'WebSocketService', 'GlyphService', 'PanelService', 'DialogService',
function (_$log_, _fs_, _wss_, _gs_, _ps_, _ds_) {
$log = _$log_;
fs = _fs_;
wss = _wss_;
gs = _gs_;
ps = _ps_;
ds = _ds_;
var handlers = {},
vtapOverlay = 'vtap-overlay',
defaultOverlay = 'traffic';
handlers[osvIsActResp] = respIsActCb;
handlers[osvCreateResp] = respCreateCb;
wss.bindHandlers(handlers);
return {
displayVtap: displayVtap
};
}])
.run(['$log', 'TopoOverlayService', 'OpenstackVtapTopovService', 'TopoTrafficService',
function (_$log_, _tov_, _ovts_, _tts_) {
$log = _$log_;
tov = _tov_;
ovts = _ovts_;
tts = _tts_;
tov.register(overlay);
}]
);
}());

View File

@ -0,0 +1,30 @@
{
"type": "object",
"required": [
"network"
],
"properties": {
"network": {
"type": "object",
"required": [
"mode",
"networkId",
"serverIp"
],
"properties": {
"mode": {
"type": "string",
"example": "GRE"
},
"networkId": {
"type": "int",
"example": 1000
},
"serverIp": {
"type": "string",
"example": "10.20.0.1"
}
}
}
}
}

View File

@ -0,0 +1 @@
<link rel="stylesheet" href="app/view/openstackvtap/openstackvtap.css">

View File

@ -0,0 +1 @@
<script src="app/view/openstackvtap/openstackvtap.js"></script>

View File

@ -18,7 +18,7 @@
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="ONOS" version="2.5">
<display-name>Openstack vTap REST API v1.0</display-name>
<display-name>Openstack Vtap REST API v1.0</display-name>
<security-constraint>
<web-resource-collection>

View File

@ -34,8 +34,8 @@ import static org.hamcrest.Matchers.is;
*/
public class DefaultOpenstackVtapTest {
private static final OpenstackVtapId VTAP_ID_1 = OpenstackVtapId.vTapId();
private static final OpenstackVtapId VTAP_ID_2 = OpenstackVtapId.vTapId();
private static final OpenstackVtapId VTAP_ID_1 = OpenstackVtapId.vtapId();
private static final OpenstackVtapId VTAP_ID_2 = OpenstackVtapId.vtapId();
private static final OpenstackVtap.Type VTAP_TYPE_1 = OpenstackVtap.Type.VTAP_TX;
private static final OpenstackVtap.Type VTAP_TYPE_2 = OpenstackVtap.Type.VTAP_RX;
@ -74,10 +74,9 @@ public class DefaultOpenstackVtapTest {
vtap1 = builder1
.id(VTAP_ID_1)
.type(VTAP_TYPE_1)
.vTapCriterion(CRITERION_1)
.vtapCriterion(CRITERION_1)
.txDeviceIds(Sets.newHashSet())
.rxDeviceIds(Sets.newHashSet())
.annotations()
.build();
OpenstackVtap.Builder builder2 = DefaultOpenstackVtap.builder();
@ -85,10 +84,9 @@ public class DefaultOpenstackVtapTest {
sameAsVtap1 = builder2
.id(VTAP_ID_1)
.type(VTAP_TYPE_1)
.vTapCriterion(CRITERION_1)
.vtapCriterion(CRITERION_1)
.txDeviceIds(Sets.newHashSet())
.rxDeviceIds(Sets.newHashSet())
.annotations()
.build();
OpenstackVtap.Builder builder3 = DefaultOpenstackVtap.builder();
@ -96,10 +94,9 @@ public class DefaultOpenstackVtapTest {
vtap2 = builder3
.id(VTAP_ID_2)
.type(VTAP_TYPE_2)
.vTapCriterion(CRITERION_2)
.vtapCriterion(CRITERION_2)
.txDeviceIds(Sets.newHashSet())
.rxDeviceIds(Sets.newHashSet())
.annotations()
.build();
}
@ -116,7 +113,7 @@ public class DefaultOpenstackVtapTest {
DefaultOpenstackVtap vtap = (DefaultOpenstackVtap) vtap1;
assertThat(vtap.id(), is(VTAP_ID_1));
assertThat(vtap.vTapCriterion(), is(CRITERION_1));
assertThat(vtap.vtapCriterion(), is(CRITERION_1));
assertThat(vtap.type(), is(VTAP_TYPE_1));
}