Add support for network connections

This commit is contained in:
Alexandru Coman 2017-02-06 13:50:56 +02:00
parent 8a00e068a1
commit ac78a59069
No known key found for this signature in database
GPG Key ID: A7B6A9021F704507
6 changed files with 732 additions and 30 deletions

View File

@ -80,9 +80,13 @@ class _BaseHNVModel(model.Model):
optional element but it is suggested that all clients fill in the data optional element but it is suggested that all clients fill in the data
that is applicable to them.""" that is applicable to them."""
etag = model.Field(name="etag", key="etag", is_property=False) etag = model.Field(name="etag", key="etag", is_property=False,
is_read_only=True)
"""An opaque string representing the state of the resource at the """An opaque string representing the state of the resource at the
time the response was generated.""" time the response was generated. This header is returned for
requests that target a single entity. The Network Controller will
also always return an etag in the response body. The etag is
updated every time the resource is updated."""
tags = model.Field(name="tags", key="tags", is_property=False, tags = model.Field(name="tags", key="tags", is_property=False,
is_required=False) is_required=False)
@ -93,6 +97,12 @@ class _BaseHNVModel(model.Model):
"""Indicates the various states of the resource. Valid values are """Indicates the various states of the resource. Valid values are
Deleting, Failed, Succeeded, and Updating.""" Deleting, Failed, Succeeded, and Updating."""
configuration_state = model.Field(name="configuration_state",
key="configurationState",
is_read_only=True, is_required=False)
""""Configuration state indicates any failures in processing state
corresponding to the resource it is contained in."""
@staticmethod @staticmethod
def _get_client(): def _get_client():
"""Create a new client for the HNV REST API.""" """Create a new client for the HNV REST API."""
@ -212,11 +222,18 @@ class _BaseHNVModel(model.Model):
@classmethod @classmethod
def from_raw_data(cls, raw_data): def from_raw_data(cls, raw_data):
"""Create a new model using raw API response.""" """Create a new model using raw API response."""
properties = raw_data.get("properties", {})
raw_metadata = raw_data.get("resourceMetadata", None) raw_metadata = raw_data.get("resourceMetadata", None)
if raw_metadata is not None: if raw_metadata is not None:
metadata = ResourceMetadata.from_raw_data(raw_metadata) metadata = ResourceMetadata.from_raw_data(raw_metadata)
raw_data["resourceMetadata"] = metadata raw_data["resourceMetadata"] = metadata
raw_state = properties.get("configurationState", None)
if raw_state is not None:
configuration = ConfigurationState.from_raw_data(raw_state)
properties["configurationState"] = configuration
return super(_BaseHNVModel, cls).from_raw_data(raw_data) return super(_BaseHNVModel, cls).from_raw_data(raw_data)
@ -655,10 +672,6 @@ class NetworkInterfaces(_BaseHNVModel):
_endpoint = "/networking/v1/networkInterfaces/{resource_id}" _endpoint = "/networking/v1/networkInterfaces/{resource_id}"
configuration_state = model.Field(name="configuration_state",
key="configurationState",
is_read_only=True, is_required=False)
dns_settings = model.Field(name="dns_settings", key="dnsSettings", dns_settings = model.Field(name="dns_settings", key="dnsSettings",
is_read_only=False) is_read_only=False)
"""Indicates the DNS settings of this network interface.""" """Indicates the DNS settings of this network interface."""
@ -733,10 +746,6 @@ class NetworkInterfaces(_BaseHNVModel):
port_settings = PortSettings.from_raw_data(raw_settings) port_settings = PortSettings.from_raw_data(raw_settings)
properties["portSettings"] = port_settings properties["portSettings"] = port_settings
raw_state = properties.get("configurationState", {})
configuration = ConfigurationState.from_raw_data(raw_state)
properties["configurationState"] = configuration
return super(NetworkInterfaces, cls).from_raw_data(raw_data) return super(NetworkInterfaces, cls).from_raw_data(raw_data)
@ -824,11 +833,6 @@ class VirtualNetworks(_BaseHNVModel):
_endpoint = "/networking/v1/virtualNetworks/{resource_id}" _endpoint = "/networking/v1/virtualNetworks/{resource_id}"
configuration_state = model.Field(name="configuration_state",
key="configurationState",
is_read_only=True)
"""Indicates the last known running state of this resource."""
address_space = model.Field(name="address_space", address_space = model.Field(name="address_space",
key="addressSpace", key="addressSpace",
is_required=True) is_required=True)
@ -864,11 +868,6 @@ class VirtualNetworks(_BaseHNVModel):
if raw_network: if raw_network:
properties["logicalNetwork"] = Resource.from_raw_data(raw_network) properties["logicalNetwork"] = Resource.from_raw_data(raw_network)
raw_config = properties.get("configurationState")
if raw_config:
config = ConfigurationState.from_raw_data(raw_config)
properties["configurationState"] = config
return super(VirtualNetworks, cls).from_raw_data(raw_data) return super(VirtualNetworks, cls).from_raw_data(raw_data)
@ -968,11 +967,6 @@ class AccessControlLists(_BaseHNVModel):
_endpoint = "/networking/v1/accessControlLists/{resource_id}" _endpoint = "/networking/v1/accessControlLists/{resource_id}"
configuration_state = model.Field(name="configuration_state",
key="configurationState",
is_read_only=True)
"""Indicates the last known running state of this resource."""
acl_rules = model.Field(name="acl_rules", key="aclRules") acl_rules = model.Field(name="acl_rules", key="aclRules")
"""Indicates the rules in an access control list.""" """Indicates the rules in an access control list."""
@ -1013,10 +1007,6 @@ class AccessControlLists(_BaseHNVModel):
acl_rules.append(ACLRules.from_raw_data(raw_rule)) acl_rules.append(ACLRules.from_raw_data(raw_rule))
properties["aclRules"] = acl_rules properties["aclRules"] = acl_rules
raw_state = properties.get("configurationState", {})
configuration = ConfigurationState.from_raw_data(raw_state)
properties["configurationState"] = configuration
return super(AccessControlLists, cls).from_raw_data(raw_data) return super(AccessControlLists, cls).from_raw_data(raw_data)
@ -1186,3 +1176,494 @@ class RouteTables(_BaseHNVModel):
properties["subnets"] = subnets properties["subnets"] = subnets
return super(RouteTables, cls).from_raw_data(raw_data) return super(RouteTables, cls).from_raw_data(raw_data)
class MainMode(model.Model):
"""Main mode IPsec configuration details."""
diffie_hellman_group = model.Field(
name="diffie_hellman_group", key="diffieHellmanGroup",
is_required=False, is_read_only=False, is_property=False)
"""Indicates Diffie Hellman group used during main mode IKE negotiation.
Values: `Group1`, `Group2`, `Group14`, `ECP256`, `ECP384` or `Group24`."""
integrity_algorithm = model.Field(
name="integrity_algorithm", key="integrityAlgorithm",
is_required=False, is_read_only=False, is_property=False)
"""Indicates Integrity algorithm used during main mode IKE negotiation.
Values: `MD5`, `SHA196`, `SHA256` or `SHA384`."""
encryption_algorithm = model.Field(
name="encryption_algorithm", key="encryptionAlgorithm",
is_required=False, is_read_only=False, is_property=False)
"""Indicates cipher algorithm used during main mode IKE negotiation.
Values: `DES`, `DES3`, `AES128`, `AES192` or `AES256`."""
sa_life_time_seconds = model.Field(
name="sa_life_time_seconds", key="saLifeTimeSeconds",
is_required=False, is_read_only=False, is_property=False)
"""Indicates life time of SA in seconds."""
sa_life_time_kb = model.Field(
name="sa_life_time_kb", key="saLifeTimeKiloBytes",
is_required=False, is_read_only=False, is_property=False)
"""Indicates life time of SA in Kilobytes. Ignored by IPsec."""
class QuickMode(model.Model):
"""Quick mode IPsec configuration"""
perfect_forward_secrecy = model.Field(
name="perfect_forward_secrecy", key="perfectForwardSecrecy",
is_required=False, is_read_only=False, is_property=False)
"""Indicates whether Perfect Forward Secrecy is enabled or not. If enabled
specifies the algorithm.
Values: `None`, `PFS1`, `PFS2`, `PFS2048`, `PFS14`, `ECP256`, `ECP384`,
`PFSMM` or `PFS24`."""
cipher_tc = model.Field(
name="cipher_tc", key="cipherTransformationConstant",
is_required=False, is_read_only=False, is_property=False)
"""Indicates the encryption algorithm used for data traffic.
Values:
None, `constant.AES128`, `constant.AES128CBC`, `constant.AES192`,
`constant.AES192CBC`, `constant.AES256`, `constant.AES256`,
`constant.CBCDES`, `constant.CBCDES3`, `constant.DES`, `constant.DES3`,
`constant.GCMAES128`, `constant.GCMAES192` or `constant.GCMAES256`.
"""
authentication_tc = model.Field(
name="authentication_tc", key="authenticationTransformationConstant",
is_required=False, is_read_only=False, is_property=False)
"""Indicates the authentication transform used for data traffic.
Values: `constant.MD596`, `constant.SHA196`, `constant.SHA256`,
`constant.GCMAES128`, `constant.GCMAES192` or `constant.GCMAES256`."""
sa_life_time_seconds = model.Field(
name="sa_life_time_seconds", key="saLifeTimeSeconds",
is_required=False, is_read_only=False, is_property=False)
"""Indicates life time of SA in seconds."""
sa_life_time_kb = model.Field(
name="sa_life_time_kb", key="saLifeTimeKiloBytes",
is_required=False, is_read_only=False, is_property=False)
"""Indicates life time of SA in Kilobytes."""
idle_disconnect = model.Field(
name="idle_disconnect", key="idleDisconnectSeconds",
is_required=False, is_read_only=False, is_property=False)
"""Indicates idle time after which SA is disconnected."""
class _VpnTrafficSelector(model.Model):
"""Model for VPN traffice selector."""
ts_type = model.Field(
name="ts_type", key="type",
is_required=False, is_read_only=False, is_property=False)
"""Indicates whether traffic is `IPv4` or `IPv6`."""
protocol_id = model.Field(
name="protocol_id", key="protocolId",
is_required=False, is_read_only=False, is_property=False)
"""Indicates IP protocol ID (such as UDP, TCP, and ICMP)."""
port_start = model.Field(
name="port_start", key="portStart",
is_required=False, is_read_only=False, is_property=False)
"""Indicates start of port range."""
port_end = model.Field(
name="port_end", key="portEnd",
is_required=False, is_read_only=False, is_property=False)
"""Indicates end of port range."""
ip_address_start = model.Field(
name="ip_address_start", key="ipAddressStart",
is_required=False, is_read_only=False, is_property=False)
"""Indicates start of IP addresses."""
ip_address_end = model.Field(
name="ip_address_end", key="ipAddressEnd",
is_required=False, is_read_only=False, is_property=False)
"""Indicates end of IP addresses."""
ts_payload_id = model.Field(
name="ts_payload_id", key="tsPayloadId",
is_required=False, is_read_only=False, is_property=False)
"""No information available for this field."""
class LocalVpnTrafficSelector(_VpnTrafficSelector):
"""Model for local VPN traffic selector.
Indicates collection of IPsec TrafficSelectors on the hoster side.
"""
pass
class RemoteVpnTrafficSelector(_VpnTrafficSelector):
"""Model for remote VPN traffic selector.
Indicates collection of IPsec TrafficSelectors on the tenant side.
"""
pass
class IPSecConfiguration(model.Model):
"""Details of IPsec configuration."""
authentication_method = model.Field(
name="authentication_method", key="authenticationMethod",
is_required=False, is_read_only=False, is_property=False,
default="PSK")
"""Indicates authentication method. PSK is the only valid value."""
shared_secret = model.Field(
name="shared_secret", key="sharedsecret",
is_required=False, is_read_only=False, is_property=False)
"""The shared secret used for this NetworkConnection.
Note this is write-only property and the value of this field is not
shown in the GET of Networkconnection."""
main_mode = model.Field(
name="main_mode", key="mainMode",
is_required=False, is_read_only=False, is_property=False)
"""Main mode IPsec configuration details."""
quick_mode = model.Field(
name="quick_mode", key="quickMode",
is_required=False, is_read_only=False, is_property=False)
"""Quick mode IPsec configuration."""
local_vpn_ts = model.Field(
name="local_vpn_ts", key="localVpnTrafficSelector",
is_required=False, is_read_only=False, is_property=False)
"""Indicates collection of IPsec TrafficSelectors on the hoster side."""
remote_vpn_ts = model.Field(
name="remote_vpn_ts", key="remoteVpnTrafficSelector",
is_required=False, is_read_only=False, is_property=False)
"""Indicates collection of IPsec TrafficSelectors on the tenant side."""
@classmethod
def from_raw_data(cls, raw_data):
"""Create a new model using raw API response."""
raw_main = raw_data.pop("mainMode", None)
if raw_main is not None:
main_mode = MainMode.from_raw_data(raw_main)
raw_data["mainMode"] = main_mode
raw_quick = raw_data.get("quickMode", None)
if raw_quick is not None:
quick_mode = QuickMode.from_raw_data(raw_quick)
raw_data["quickMode"] = quick_mode
local_vpn_ts = []
for raw_local_vpn in raw_data.get("localVpnTrafficSelector", []):
local_vpn_ts.append(LocalVpnTrafficSelector.from_raw_data(
raw_local_vpn))
raw_data["localVpnTrafficSelector"] = local_vpn_ts
remote_vpn_ts = []
for raw_remote_vpn in raw_data.get("remoteVpnTrafficSelector", []):
remote_vpn_ts.append(RemoteVpnTrafficSelector.from_raw_data(
raw_remote_vpn))
raw_data["remoteVpnTrafficSelector"] = remote_vpn_ts
return super(IPSecConfiguration, cls).from_raw_data(raw_data)
class IPAddress(model.Model):
"""IP assigned in the tenant compartment for L3 interface."""
ip_address = model.Field(
name="ip_address", key="ipAddress",
is_required=False, is_read_only=False, is_property=False)
"""IP address for L3 interface in tenant compartment."""
prefix_length = model.Field(
name="prefix_length", key="prefixLength",
is_required=False, is_read_only=False, is_property=False)
"""Prefix length of the IP address."""
class NetworkInterfaceRoute(model.Model):
"""Model for network interface route."""
destination_prefix = model.Field(
name="destination_prefix", key="destinationPrefix",
is_required=True, is_read_only=False, is_property=False)
"""Prefix with subnet of the routes."""
next_hop = model.Field(
name="next_hop", key="nextHop",
is_required=False, is_read_only=False, is_property=False)
"""Next Hop of the routes. Is significant only for L3 connections.
Has no significance for point to point connections such as IPsec & GRE."""
metric = model.Field(
name="metric", key="metric",
is_required=False, is_read_only=False, is_property=False)
"""Indicates Metric of the route."""
protocol = model.Field(
name="protocol", key="protocol",
is_required=False, is_read_only=False, is_property=False)
"""Indicates how the route is learnt/added (`static` or `BGP`)."""
class NetworkInterfaceStatistics(model.Model):
"""Model for network interface statistics."""
outbound_bytes = model.Field(
name="outbound_bytes", key="outboundBytes",
is_required=False, is_read_only=True, is_property=False)
"""Indicates number of bytes transmitted."""
inbound_bytes = model.Field(
name="inbound_bytes", key="inboundBytes",
is_required=False, is_read_only=True, is_property=False)
"""Indicates number of bytes received."""
rx_total_packets_dropped = model.Field(
name="rx_total_packets_dropped", key="rxTotalPacketsDropped",
is_required=False, is_read_only=True, is_property=False)
"""Indicates number of packets dropped in ingress direction."""
tx_total_packets_dropped = model.Field(
name="tx_total_packets_dropped", key="txTotalPacketsDropped",
is_required=False, is_read_only=True, is_property=False)
"""Indicates number of packets dropped in egress direction."""
tx_rate_kbps = model.Field(
name="tx_rate_kbps", key="txRateKbps",
is_required=False, is_read_only=True, is_property=False)
"""Indicates rate at which traffic is going out in Kbps."""
rx_rate_kbps = model.Field(
name="rx_rate_kbps", key="rxRateKbps",
is_required=False, is_read_only=True, is_property=False)
"""Indicates rate at which traffic is coming in in Kbps."""
tx_rate_limited_packets_dropped = model.Field(
name="tx_rate_limited_packets_dropped",
key="txRateLimitedPacketsDropped",
is_required=False, is_read_only=True, is_property=False)
"""Indicates number of packets dropped in egress direction due to
rate limiting."""
rx_rate_limited_packets_dropped = model.Field(
name="rx_rate_limited_packets_dropped",
key="rxRateLimitedPacketsDropped",
is_required=False, is_read_only=True, is_property=False)
"""Indicates number of packets dropped in ingress direction due to
rate limiting."""
last_updated = model.Field(
name="last_updated", key="lastUpdated",
is_required=False, is_read_only=True, is_property=False)
"""Indicates the time the statistics were last updated."""
class GREConfiguration(model.Model):
"""Model for GRE configuration.
Indicates details of GRE configuration.
"""
gre_key = model.Field(
name="gre_key", key="greKey",
is_required=False, is_read_only=False, is_property=False)
"""Indicates GRE key."""
class L3Configuration(model.Model):
"""Model for L3 configuration.
Indicates details of L3 configuration.
"""
vlan_subnet = model.Field(
name="vlan_subnet", key="vlanSubnet",
is_required=False, is_read_only=False, is_property=False)
"""Reference to a logical subnet of L3 connection."""
class NetworkConnections(_BaseHNVModel):
"""Model for network connections.
The networkConnections resource specifies a connection from virtual
network to external networks.
Multiple connections can exist for a given virtual network and there
are different types of connections.
"""
_endpoint = ("/networking/v1/virtualGateways/{parent_id}"
"/networkConnections/{resource_id}")
parent_id = model.Field(name="parent_id",
key="parentResourceID",
is_property=False, is_required=True,
is_read_only=True)
"""The parent resource ID field contains the resource ID that is
associated with network objects that are ancestors of the necessary
resource.
"""
connection_type = model.Field(name="connection_type", key="connectionType",
is_required=False, is_read_only=False)
"""Indicates type of connection. Valid keys are `constant.IPSSEC`,
`constant.GRE` and `constant.L3`."""
outbound_kbps = model.Field(name="outbound_kbps",
key="outboundKiloBitsPerSecond",
is_required=False, is_read_only=False)
"""Indicates maximum allowed outbound bandwidth in Kbps."""
inbound_bbps = model.Field(name="inbound_bbps",
key="inboundKiloBitsPerSecond",
is_required=False, is_read_only=False)
"""Indicates maximum allowed outbound bandwidth in Kbps."""
ipsec_configuration = model.Field(name="ipsec_configuration",
key="ipSecConfiguration",
is_required=False, is_read_only=False)
"""Details of IPsec configuration."""
ip_address = model.Field(name="ip_address", key="IpAddress",
is_required=False, is_read_only=False)
"""Indicates ConnecTo Address to which peers connect to and which is
the source IP address in egress direction. This would be the VIP."""
ip_addresses = model.Field(name="ip_addresses", key="ipAddresses",
is_required=False, is_read_only=False)
"""IP assigned in the tenant compartment for L3 interface."""
peer_ip_address = model.Field(name="peer_ip_address",
key="peerIPAddresses",
is_required=False, is_read_only=False)
"""Indicates peer IP address to which connection is made."""
source_ip_address = model.Field(name="source_ip_address",
key="sourceIPAddress",
is_required=False, is_read_only=False)
"""Indicates sourceIPAddress used by the tunnel. Applicable to
IKEv2 and GRE."""
destination_ip_address = model.Field(name="destination_ip_address",
key="destinationIPAddress",
is_required=False, is_read_only=False)
"""Indicates destination ip address of the tunnel. Applicable to
IKEv2 and GRE."""
routes = model.Field(name="routes", key="routes",
is_required=False, is_read_only=False)
"""List of all the routes (static and those learned via BGP) on the
network interface. Traffic matching the routes is transmitted on the
network interface.
"""
connection_status = model.Field(name="connection_status",
key="connectionStatus",
is_required=False, is_read_only=False)
"""Indicates administrative status of connection.
Values: `enabled` or `disabled`."""
connection_state = model.Field(name="connection_state",
key="connectionState",
is_required=False, is_read_only=False)
"""Indicates operational status of connection.
Values: `Connected` or `Disconnected`.
"""
statistics = model.Field(name="statistics", key="statistics",
is_required=False, is_read_only=False)
"""Statistics of the connection."""
connection_uptime = model.Field(name="connection_uptime",
key="connectionUpTime",
is_required=False, is_read_only=True)
"""Indicates operations up time of the connection in seconds."""
connection_error_reason = model.Field(name="connection_error_reason",
key="connectionErrorReason",
is_required=False,
is_read_only=True)
"""Indicates the reason for not being able to connect after dialling
in the previous attempt."""
unreachability_reason = model.Field(name="unreachability_reason",
key="unreachabilityReason",
is_required=False, is_read_only=True)
"""Indicates the reason for not being able to connect/dial in the
previous attempt."""
gre_configuration = model.Field(name="gre_configuration",
key="greConfiguration",
is_required=False, is_read_only=False)
"""Indicates details of GRE configuration."""
l3_configuration = model.Field(name="l3_configuration",
key="l3Configuration",
is_required=False, is_read_only=False)
"""Indicates details of L3 configuration."""
gateway = model.Field(name="gateway", key="gateway",
is_required=False, is_read_only=False)
@classmethod
def from_raw_data(cls, raw_data):
"""Create a new model using raw API response."""
properties = raw_data.get("properties", {})
raw_content = properties.get("ipSecConfiguration", None)
if raw_content is not None:
ip_sec = IPSecConfiguration.from_raw_data(raw_content)
properties["ipSecConfiguration"] = ip_sec
ip_addresses = []
for raw_content in properties.get("ipAddresses", []):
ip_addresses.append(IPAddress.from_raw_data(raw_content))
properties["ipAddresses"] = ip_addresses
routes = []
for raw_content in properties.get("routes", []):
routes.append(NetworkInterfaceRoute.from_raw_data(raw_content))
properties["routes"] = routes
raw_content = properties.get("statistics", None)
if raw_content is not None:
statistics = NetworkInterfaceStatistics.from_raw_data(
raw_content)
properties["statistics"] = statistics
raw_content = properties.get("greConfiguration", None)
if raw_content is not None:
gre_configuration = GREConfiguration.from_raw_data(raw_content)
properties["greConfiguration"] = gre_configuration
raw_content = properties.get("l3Configuration", None)
if raw_content is not None:
l3_configuration = L3Configuration.from_raw_data(raw_content)
properties["l3Configuration"] = l3_configuration
raw_content = properties.get("gateway", None)
if raw_content is not None:
gateway = Resource.from_raw_data(raw_content)
properties["gateway"] = gateway
return super(NetworkConnections, cls).from_raw_data(raw_data)

View File

@ -32,3 +32,32 @@ VIRTUAL_APPLIANCE = "VirtualAppliance"
VNET_LOCAL = "VnetLocal" VNET_LOCAL = "VnetLocal"
VIRTUAL_NETWORK_GATEWAY = "VirtualNetworkGateway" VIRTUAL_NETWORK_GATEWAY = "VirtualNetworkGateway"
INTERNET = "Internet" INTERNET = "Internet"
# Network connections: Connection type
IPSEC = "IPSec"
GRE = "GRE"
L3 = "L3"
# Cipher transformation constant
NONE = "None"
AES128 = "AES128"
AES128CBC = "AES128CBC"
AES192 = "AES192"
AES192CBC = "AES192CBC"
AES256 = "AES256"
AES256 = "AES256"
CBCDES = "CBCDES"
CBCDES3 = "CBCDES3"
DES = "DES"
DES3 = "DES3"
GCMAES128 = "GCMAES128"
GCMAES192 = "GCMAES192"
GCMAES256 = "GCMAES256"
# Authentication tranformation constant
MD596 = "MD596"
SHA196 = "SHA196"
SHA256 = "SHA256"
GCMAES128 = "GCMAES128"
GCMAES192 = "GCMAES192"
GCMAES256 = "GCMAES256"

View File

@ -265,13 +265,14 @@ class Model(object):
setattr(self, field.name, value) setattr(self, field.name, value)
if fields: if fields:
LOG.debug("Unrecognized fields: %r", fields) LOG.debug("Ignored fields: %r", fields)
@classmethod @classmethod
def process_raw_data(cls, raw_data): def process_raw_data(cls, raw_data):
"""Process the received data in order to be understood by the model.""" """Process the received data in order to be understood by the model."""
content = {} content = {}
properties = raw_data.pop("properties", {}) properties = raw_data.pop("properties", {})
for field_name, field in cls._meta.fields.items(): for field_name, field in cls._meta.fields.items():
if field.is_property: if field.is_property:
value = properties.pop(field.key, None) value = properties.pop(field.key, None)
@ -282,6 +283,7 @@ class Model(object):
if raw_data: if raw_data:
LOG.debug("Unrecognized fields: %r for %r", LOG.debug("Unrecognized fields: %r for %r",
raw_data, cls.__name__) raw_data, cls.__name__)
if properties: if properties:
LOG.debug("Unrecognized properties: %r for %r", LOG.debug("Unrecognized properties: %r for %r",
properties, cls.__name__) properties, cls.__name__)

View File

@ -81,3 +81,7 @@ class FakeResponse(object):
def route_tables(self): def route_tables(self):
"""Fake GET(all) response for route tables.""" """Fake GET(all) response for route tables."""
return self._load_resource("route_tables.json") return self._load_resource("route_tables.json")
def network_connections(self):
"""Fake GET(all) response for network connections."""
return self._load_resource("network_connections.json")

View File

@ -0,0 +1,179 @@
{
"value": [
{
"resourceRef": "/VirtualGateways/VirtualGatewayTenant_1/NetworkConnections/VirtualGatewayTenant_1_IPSEC_1",
"resourceId": "VirtualGatewayTenant_1_IPSEC_1",
"etag": "W/\"8559fe48-df3e-4765-8515-e43151d93cfeae62a1d6-a1ea-48a7-a122-56db52d5e7ee\"",
"instanceId": "a192d851-0849-4d88-a0d5-86647f1b9efc827c5920-ce65-4175-a18f-6dfd84538a14",
"properties": {
"provisioningState": "Succeeded",
"connectionType": "IPSec",
"outboundKiloBitsPerSecond": 1000,
"inboundKiloBitsPerSecond": 1000,
"ipSecConfiguration": {
"authenticationMethod": "PSK",
"quickMode": {
"perfectForwardSecrecy": "PFS2048",
"cipherTransformationConstant": "DES3",
"authenticationTransformationConstant": "SHA256128",
"idleDisconnectSeconds": 500,
"saLifeTimeSeconds": 1233,
"saLifeTimeKiloBytes": 2000
},
"mainMode": {
"diffieHellmanGroup": "Group2",
"encryptionAlgorithm": "AES256",
"integrityAlgorithm": "SHA256",
"saLifeTimeSeconds": 1234,
"saLifeTimeKiloBytes": 2000
},
"localVpnTrafficSelector": [
{
"type": "IPv4",
"protocolId": 0,
"portStart": 0,
"portEnd": 65535,
"ipAddressStart": "0.0.0.0",
"ipAddressEnd": "255.255.255.255",
"tsPayloadId": 0
}
],
"remoteVpnTrafficSelector": [
{
"type": "IPv4",
"protocolId": 0,
"portStart": 0,
"portEnd": 65535,
"ipAddressStart": "0.0.0.0",
"ipAddressEnd": "255.255.255.255",
"tsPayloadId": 0
}
]
},
"l3Configuration": {},
"ipAddresses": [],
"peerIPAddresses": [],
"routes": [
{
"destinationPrefix": "10.2.3.0/24",
"metric": 10,
"protocol": "Static"
}
],
"connectionStatus": "Enabled",
"connectionErrorReason": "809",
"unreachabilityReason": "ConnectionFailure",
"statistics": {
"outboundBytes": 0,
"inboundBytes": 0,
"rxTotalPacketsDropped": 0,
"txTotalPacketsDropped": 0,
"txRateKbps": 0,
"rxRateKbps": 0,
"txRateLimitedPacketsDropped": 0,
"rxRateLimitedPacketsDropped": 0,
"lastUpdated": "2016-01-14T08:26:37.8964269Z"
},
"configurationState": {
"status": "Success",
"lastUpdatedTime": "2016-02-19T02:48:49.3532316-08:00"
},
"sourceIPAddress": "91.1.1.4",
"destinationIPAddress": "11.1.0.1",
"connectionState": "Disconnected",
"connectionUpTime": "00:00:00",
"gateway": {
"resourceRef": "/Gateways/CloudGw1"
}
}
},
{
"resourceRef": "/VirtualGateways/VirtualGatewayTenant_1/NetworkConnections/VirtualGatewayTenant_1_IPSEC_1",
"resourceId": "VirtualGatewayTenant_1_IPSEC_1",
"etag": "W/\"8559fe48-df3e-4765-8515-e43151d93cfeae62a1d6-a1ea-48a7-a122-56db52d5e7ee\"",
"instanceId": "a192d851-0849-4d88-a0d5-86647f1b9efc827c5920-ce65-4175-a18f-6dfd84538a14",
"properties": {
"provisioningState": "Succeeded",
"connectionType": "IPSec",
"outboundKiloBitsPerSecond": 1000,
"inboundKiloBitsPerSecond": 1000,
"ipSecConfiguration": {
"authenticationMethod": "PSK",
"quickMode": {
"perfectForwardSecrecy": "PFS2048",
"cipherTransformationConstant": "DES3",
"authenticationTransformationConstant": "SHA256128",
"idleDisconnectSeconds": 500,
"saLifeTimeSeconds": 1233,
"saLifeTimeKiloBytes": 2000
},
"mainMode": {
"diffieHellmanGroup": "Group2",
"encryptionAlgorithm": "AES256",
"integrityAlgorithm": "SHA256",
"saLifeTimeSeconds": 1234,
"saLifeTimeKiloBytes": 2000
},
"localVpnTrafficSelector": [
{
"type": "IPv4",
"protocolId": 0,
"portStart": 0,
"portEnd": 65535,
"ipAddressStart": "0.0.0.0",
"ipAddressEnd": "255.255.255.255",
"tsPayloadId": 0
}
],
"remoteVpnTrafficSelector": [
{
"type": "IPv4",
"protocolId": 0,
"portStart": 0,
"portEnd": 65535,
"ipAddressStart": "0.0.0.0",
"ipAddressEnd": "255.255.255.255",
"tsPayloadId": 0
}
]
},
"l3Configuration": {},
"ipAddresses": [],
"peerIPAddresses": [],
"routes": [
{
"destinationPrefix": "10.2.3.0/24",
"nextHop": "0.0.0.0",
"metric": 10,
"protocol": "Static"
}
],
"connectionStatus": "Enabled",
"connectionErrorReason": "809",
"unreachabilityReason": "ConnectionFailure",
"statistics": {
"outboundBytes": 0,
"inboundBytes": 0,
"rxTotalPacketsDropped": 0,
"txTotalPacketsDropped": 0,
"txRateKbps": 0,
"rxRateKbps": 0,
"txRateLimitedPacketsDropped": 0,
"rxRateLimitedPacketsDropped": 0,
"lastUpdated": "2016-01-14T08:26:37.8964269Z"
},
"configurationState": {
"status": "Success",
"lastUpdatedTime": "2016-02-19T02:48:49.3532316-08:00"
},
"sourceIPAddress": "91.1.1.4",
"destinationIPAddress": "11.1.0.1",
"connectionState": "Disconnected",
"connectionUpTime": "00:00:00",
"gateway": {
"resourceRef": "/Gateways/CloudGw1"
}
}
}
]
}

View File

@ -172,6 +172,7 @@ class TestClient(unittest.TestCase):
def setUp(self): def setUp(self):
self._response = fake_response.FakeResponse() self._response = fake_response.FakeResponse()
self.maxDiff = None
def _test_get_resource(self, model, raw_data): def _test_get_resource(self, model, raw_data):
with test_utils.LogSnatcher("hnv.common.model") as logging: with test_utils.LogSnatcher("hnv.common.model") as logging:
@ -287,3 +288,9 @@ class TestClient(unittest.TestCase):
for raw_data in resources.get("value", []): for raw_data in resources.get("value", []):
self._test_get_resource(model=client.RouteTables, self._test_get_resource(model=client.RouteTables,
raw_data=raw_data) raw_data=raw_data)
def test_network_connections(self):
resources = self._response.network_connections()
for raw_data in resources.get("value", []):
self._test_get_resource(model=client.NetworkConnections,
raw_data=raw_data)