Add support for logical networks
This commit is contained in:
parent
52f8d3e54e
commit
488af328cf
@ -44,6 +44,23 @@ class _BaseHNVModel(model.Model):
|
|||||||
the context of the resource if it is a top-level resource, or in the
|
the context of the resource if it is a top-level resource, or in the
|
||||||
context of the direct parent resource if it is a child resource."""
|
context of the direct parent resource if it is a child resource."""
|
||||||
|
|
||||||
|
parent_id = model.Field(name="parent_id",
|
||||||
|
key="parentResourceID",
|
||||||
|
is_property=False, is_required=False,
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
|
||||||
|
grandparent_id = model.Field(name="grandparent_id",
|
||||||
|
key="grandParentResourceID",
|
||||||
|
is_property=False, is_required=False,
|
||||||
|
is_read_only=True)
|
||||||
|
"""The grand parent resource ID field contains the resource ID that
|
||||||
|
is associated with network objects that are ancestors of the parent
|
||||||
|
of the necessary resource."""
|
||||||
|
|
||||||
instance_id = model.Field(name="instance_id", key="instanceId",
|
instance_id = model.Field(name="instance_id", key="instanceId",
|
||||||
is_property=False)
|
is_property=False)
|
||||||
"""The globally unique Id generated and used internally by the Network
|
"""The globally unique Id generated and used internally by the Network
|
||||||
@ -63,10 +80,6 @@ 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."""
|
||||||
|
|
||||||
def __init__(self, **fields):
|
|
||||||
self._parent_id = fields.pop("parent_id", None)
|
|
||||||
super(_BaseHNVModel, self).__init__(**fields)
|
|
||||||
|
|
||||||
@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."""
|
||||||
@ -76,11 +89,6 @@ class _BaseHNVModel(model.Model):
|
|||||||
allow_insecure=CONFIG.HNV.https_allow_insecure,
|
allow_insecure=CONFIG.HNV.https_allow_insecure,
|
||||||
ca_bundle=CONFIG.HNV.https_ca_bundle)
|
ca_bundle=CONFIG.HNV.https_ca_bundle)
|
||||||
|
|
||||||
@property
|
|
||||||
def parent_id(self):
|
|
||||||
"""The identifier for the specific ancestor resource."""
|
|
||||||
return self._parent_id
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get(cls, resource_id=None, parent_id=None):
|
def get(cls, resource_id=None, parent_id=None):
|
||||||
"""Retrieves the required resources.
|
"""Retrieves the required resources.
|
||||||
@ -187,3 +195,178 @@ class _BaseHNVModel(model.Model):
|
|||||||
self._set_fields(fields)
|
self._set_fields(fields)
|
||||||
# Lock the current model
|
# Lock the current model
|
||||||
self._provision_done = True
|
self._provision_done = True
|
||||||
|
|
||||||
|
|
||||||
|
class Resource(model.Model):
|
||||||
|
|
||||||
|
"""Model for the resource references."""
|
||||||
|
|
||||||
|
resource_ref = model.Field(name="resource_ref", key="resourceRef",
|
||||||
|
is_property=False, is_required=True)
|
||||||
|
"""A relative URI to an associated resource."""
|
||||||
|
|
||||||
|
|
||||||
|
class IPPools(_BaseHNVModel):
|
||||||
|
|
||||||
|
"""Model for IP Pools.
|
||||||
|
|
||||||
|
The ipPools resource represents the range of IP addresses from which IP
|
||||||
|
addresses will be allocated for nodes within a subnet. The subnet is a
|
||||||
|
logical or physical subnet inside a logical network.
|
||||||
|
|
||||||
|
The ipPools for a virtual subnet are implicit. The start and end IP
|
||||||
|
addresses of the pool of the virtual subnet is based on the IP prefix
|
||||||
|
of the virtual subnet.
|
||||||
|
"""
|
||||||
|
|
||||||
|
_endpoint = ("/networking/v1/logicalNetworks/{grandparent_id}"
|
||||||
|
"/logicalSubnets/{parent_id}/ipPools/{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.
|
||||||
|
"""
|
||||||
|
|
||||||
|
grandparent_id = model.Field(name="grandparent_id",
|
||||||
|
key="grandParentResourceID",
|
||||||
|
is_property=False, is_required=True,
|
||||||
|
is_read_only=True)
|
||||||
|
"""The grand parent resource ID field contains the resource ID that
|
||||||
|
is associated with network objects that are ancestors of the parent
|
||||||
|
of the necessary resource."""
|
||||||
|
|
||||||
|
start_ip_address = model.Field(name="start_ip_address",
|
||||||
|
key="startIpAddress",
|
||||||
|
is_required=True, is_read_only=False)
|
||||||
|
"""Start IP address of the pool.
|
||||||
|
Note: This is an inclusive value so it is a valid IP address from
|
||||||
|
this pool."""
|
||||||
|
|
||||||
|
end_ip_address = model.Field(name="end_ip_address", key="endIpAddress",
|
||||||
|
is_required=True, is_read_only=False)
|
||||||
|
"""End IP address of the pool.
|
||||||
|
Note: This is an inclusive value so it is a valid IP address from
|
||||||
|
this pool."""
|
||||||
|
|
||||||
|
usage = model.Field(name="usage", key="usage",
|
||||||
|
is_required=False, is_read_only=True)
|
||||||
|
"""Statistics of the usage of the IP pool."""
|
||||||
|
|
||||||
|
|
||||||
|
class LogicalSubnetworks(_BaseHNVModel):
|
||||||
|
|
||||||
|
"""Logical subnetworks model.
|
||||||
|
|
||||||
|
The logicalSubnets resource consists of a subnet/VLAN pair.
|
||||||
|
The vlan resource is required; however it MAY contain a value of zero
|
||||||
|
if the subnet is not associated with a vlan.
|
||||||
|
"""
|
||||||
|
|
||||||
|
_endpoint = ("/networking/v1/logicalNetworks/{parent_id}"
|
||||||
|
"/logicalSubnets/{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.
|
||||||
|
"""
|
||||||
|
|
||||||
|
address_prefix = model.Field(name="address_prefix", key="addressPrefix")
|
||||||
|
"""Identifies the subnet id in form of ipAddresss/prefixlength."""
|
||||||
|
|
||||||
|
vlan_id = model.Field(name="vlan_id", key="vlanId", is_required=True,
|
||||||
|
default=0)
|
||||||
|
"""Indicates the VLAN ID associated with the logical subnet."""
|
||||||
|
|
||||||
|
routes = model.Field(name="routes", key="routes", is_required=False)
|
||||||
|
"""Indicates the routes that are contained in the logical subnet."""
|
||||||
|
|
||||||
|
ip_pools = model.Field(name="ip_pools", key="ipPools",
|
||||||
|
is_required=False)
|
||||||
|
"""Indicates the IP Pools that are contained in the logical subnet."""
|
||||||
|
|
||||||
|
dns_servers = model.Field(name="dns_servers", key="dnsServers",
|
||||||
|
is_required=False)
|
||||||
|
"""Indicates one or more DNS servers that are used for resolving DNS
|
||||||
|
queries by devices or host connected to this logical subnet."""
|
||||||
|
|
||||||
|
network_interfaces = model.Field(name="network_interfaces",
|
||||||
|
key="networkInterfaces",
|
||||||
|
is_read_only=True)
|
||||||
|
"""Indicates an array of references to networkInterfaces resources
|
||||||
|
that are attached to the logical subnet."""
|
||||||
|
|
||||||
|
is_public = model.Field(name="is_public", key="isPublic")
|
||||||
|
"""Boolean flag specifying whether the logical subnet is a
|
||||||
|
public subnet."""
|
||||||
|
|
||||||
|
default_gateways = model.Field(name="default_gateways",
|
||||||
|
key="defaultGateways")
|
||||||
|
"""A collection of one or more gateways for the subnet."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_raw_data(cls, raw_data):
|
||||||
|
"""Create a new model using raw API response."""
|
||||||
|
ip_pools = []
|
||||||
|
properties = raw_data["properties"]
|
||||||
|
for raw_ip_pool in properties.get("ipPools", []):
|
||||||
|
raw_ip_pool["parentResourceID"] = raw_data["resourceId"]
|
||||||
|
raw_ip_pool["grandParentResourceID"] = raw_data["parentResourceID"]
|
||||||
|
ip_pools.append(IPPools.from_raw_data(raw_ip_pool))
|
||||||
|
properties["ipPools"] = ip_pools
|
||||||
|
|
||||||
|
return super(LogicalSubnetworks, cls).from_raw_data(raw_data)
|
||||||
|
|
||||||
|
|
||||||
|
class LogicalNetworks(_BaseHNVModel):
|
||||||
|
|
||||||
|
"""Logical networks model.
|
||||||
|
|
||||||
|
The logicalNetworks resource represents a logical partition of physical
|
||||||
|
network that is dedicated for a specific purpose.
|
||||||
|
A logical network comprises of a collection of logical subnets.
|
||||||
|
"""
|
||||||
|
|
||||||
|
_endpoint = "/networking/v1/logicalNetworks/{resource_id}"
|
||||||
|
|
||||||
|
subnetworks = model.Field(name="subnetworks", key="subnets",
|
||||||
|
is_required=False, default=[])
|
||||||
|
"""Indicates the subnets that are contained in the logical network."""
|
||||||
|
|
||||||
|
network_virtualization_enabled = model.Field(
|
||||||
|
name="network_virtualization_enabled",
|
||||||
|
key="networkVirtualizationEnabled", default=False, is_required=False)
|
||||||
|
"""Indicates if the network is enabled to be the Provider Address network
|
||||||
|
for one or more virtual networks. Valid values are `True` or `False`.
|
||||||
|
The default is `False`."""
|
||||||
|
|
||||||
|
virtual_networks = model.Field(name="virtual_networks",
|
||||||
|
key="virtualNetworks",
|
||||||
|
is_read_only=True)
|
||||||
|
"""Indicates an array of virtualNetwork resources that are using
|
||||||
|
the network."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_raw_data(cls, raw_data):
|
||||||
|
"""Create a new model using raw API response."""
|
||||||
|
properties = raw_data["properties"]
|
||||||
|
|
||||||
|
subnetworks = []
|
||||||
|
for raw_subnet in properties.get("subnets", []):
|
||||||
|
raw_subnet["parentResourceID"] = raw_data["resourceId"]
|
||||||
|
subnetworks.append(LogicalSubnetworks.from_raw_data(raw_subnet))
|
||||||
|
properties["subnets"] = subnetworks
|
||||||
|
|
||||||
|
virtual_networks = []
|
||||||
|
for raw_network in properties.get("virtualNetworks", []):
|
||||||
|
virtual_networks.append(Resource.from_raw_data(raw_network))
|
||||||
|
properties["virtualNetworks"] = virtual_networks
|
||||||
|
|
||||||
|
return super(LogicalNetworks, cls).from_raw_data(raw_data)
|
||||||
|
0
hnv_client/tests/fake/__init__.py
Normal file
0
hnv_client/tests/fake/__init__.py
Normal file
47
hnv_client/tests/fake/fake_response.py
Normal file
47
hnv_client/tests/fake/fake_response.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Copyright 2017 Cloudbase Solutions Srl
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""This module contains fake HVN API response."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
|
|
||||||
|
class FakeResponse(object):
|
||||||
|
|
||||||
|
"""HNV API fake responses."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._resources = "hnv_client.tests.fake.response"
|
||||||
|
self._cache = {}
|
||||||
|
|
||||||
|
def _load_resource(self, resource):
|
||||||
|
"""Load the json response for the required resource."""
|
||||||
|
if resource not in self._cache:
|
||||||
|
json_response = pkg_resources.resource_stream(
|
||||||
|
self._resources, resource)
|
||||||
|
self._cache[resource] = json.load(json_response)
|
||||||
|
return self._cache[resource]
|
||||||
|
|
||||||
|
def logical_networks(self):
|
||||||
|
"""Fake GET(all) response for logical networks."""
|
||||||
|
return self._load_resource("logical_networks.json")
|
||||||
|
|
||||||
|
def logical_subnets(self):
|
||||||
|
"""Fake GET(all) response for logical subnets."""
|
||||||
|
return self._load_resource("logical_subnets.json")
|
||||||
|
|
||||||
|
def ip_pools(self):
|
||||||
|
"""Fake GET(all) response for IP pools."""
|
||||||
|
return self._load_resource("ip_pools.json")
|
0
hnv_client/tests/fake/response/__init__.py
Normal file
0
hnv_client/tests/fake/response/__init__.py
Normal file
51
hnv_client/tests/fake/response/ip_pools.json
Normal file
51
hnv_client/tests/fake/response/ip_pools.json
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"resourceId": "{uniqueString}",
|
||||||
|
"etag": "00000000-0000-0000-0000-000000000000",
|
||||||
|
"instanceId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
|
||||||
|
"tags": {
|
||||||
|
"key": "value"
|
||||||
|
},
|
||||||
|
"resourceMetadata": {
|
||||||
|
"client": "<Insert likely client>",
|
||||||
|
"tenantId": "{subscriptionid}",
|
||||||
|
"groupId": "{groupname}",
|
||||||
|
"name": "{name}",
|
||||||
|
"originalHref": "https://..."
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"provisioningState": "Updating|Deleting|Failed|Succeeded",
|
||||||
|
"ipConfigurations": [],
|
||||||
|
"networkInterfaces": [],
|
||||||
|
"vlanID": "1",
|
||||||
|
"routes": [],
|
||||||
|
"dnsServers": [
|
||||||
|
"10.0.0.1",
|
||||||
|
"10.0.0.2"
|
||||||
|
],
|
||||||
|
"defaultGateways": [
|
||||||
|
"192.168.1.1",
|
||||||
|
"192.168.1.2"
|
||||||
|
],
|
||||||
|
"isPublic": true,
|
||||||
|
"ipPools": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceId": "{uniqueString}",
|
||||||
|
"etag": "00000000-0000-0000-0000-000000000000",
|
||||||
|
"instanceId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
|
||||||
|
"tags": {
|
||||||
|
"key": "value"
|
||||||
|
},
|
||||||
|
"resourceMetadata": {
|
||||||
|
"client": "<Insert likely client>",
|
||||||
|
"tenantId": "{subscriptionid}",
|
||||||
|
"groupId": "{groupname}",
|
||||||
|
"name": "{name}",
|
||||||
|
"originalHref": "https://..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
75
hnv_client/tests/fake/response/logical_networks.json
Normal file
75
hnv_client/tests/fake/response/logical_networks.json
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"resourceRef": "/logicalnetworks/72570539-58a9-43d6-b858-d7ec3f202c6d",
|
||||||
|
"resourceId": "72570539-58a9-43d6-b858-d7ec3f202c6d",
|
||||||
|
"etag": "W/\"34b565dc-c69e-4165-97ea-6e8ef6c84420\"",
|
||||||
|
"instanceId": "b75b250f-f2d1-4a2f-bb2e-57380523b407",
|
||||||
|
"properties": {
|
||||||
|
"provisioningState": "Succeeded",
|
||||||
|
"subnets": [
|
||||||
|
{
|
||||||
|
"resourceRef": "/logicalnetworks/72570539-58a9-43d6-b858-d7ec3f202c6d/subnets/3d46ae72-b1d0-48fa-b4fe-ab183e737493",
|
||||||
|
"resourceId": "3d46ae72-b1d0-48fa-b4fe-ab183e737493",
|
||||||
|
"etag": "W/\"34b565dc-c69e-4165-97ea-6e8ef6c84420\"",
|
||||||
|
"instanceId": "78c262d9-de13-4f33-a564-5f168b38a573",
|
||||||
|
"properties": {
|
||||||
|
"provisioningState": "Succeeded",
|
||||||
|
"addressPrefix": "192.83.0.0/16",
|
||||||
|
"ipConfigurations": [],
|
||||||
|
"networkInterfaces": [
|
||||||
|
{
|
||||||
|
"resourceRef": "/servers/27-3145F0416/networkInterfaces/ab055aa1-27d6-4a2e-a4b7-7916008dd1a4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"gatewayPools": [],
|
||||||
|
"networkConnections": [],
|
||||||
|
"vlanID": "109",
|
||||||
|
"ipPools": [
|
||||||
|
{
|
||||||
|
"resourceRef": "/logicalnetworks/72570539-58a9-43d6-b858-d7ec3f202c6d/subnets/3d46ae72-b1d0-48fa-b4fe-ab183e737493/ipPools/66ce16cb-7c9e-4666-b6b4-41208a497604",
|
||||||
|
"resourceId": "66ce16cb-7c9e-4666-b6b4-41208a497604",
|
||||||
|
"etag": "W/\"34b565dc-c69e-4165-97ea-6e8ef6c84420\"",
|
||||||
|
"instanceId": "0d68218b-50dc-4cc9-bb36-66324e93b407",
|
||||||
|
"properties": {
|
||||||
|
"provisioningState": "Succeeded",
|
||||||
|
"startIpAddress": "192.83.0.100",
|
||||||
|
"endIpAddress": "192.83.255.255"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceRef": "/logicalnetworks/72570539-58a9-43d6-b858-d7ec3f202c6d/subnets/3d46ae72-b1d0-48fa-b4fe-ab183e737493/ipPools/small",
|
||||||
|
"resourceId": "small",
|
||||||
|
"etag": "W/\"34b565dc-c69e-4165-97ea-6e8ef6c84420\"",
|
||||||
|
"instanceId": "581b56e7-dfb2-4fc1-833c-1aaf970c91e6",
|
||||||
|
"properties": {
|
||||||
|
"provisioningState": "Succeeded",
|
||||||
|
"startIpAddress": "192.83.0.90",
|
||||||
|
"endIpAddress": "192.83.0.98"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dnsServers": [],
|
||||||
|
"defaultGateways": [
|
||||||
|
"192.83.0.1"
|
||||||
|
],
|
||||||
|
"isPublic": false,
|
||||||
|
"usage": {
|
||||||
|
"numberOfIPAddresses": 65445,
|
||||||
|
"numberofIPAddressesAllocated": 2,
|
||||||
|
"numberOfIPAddressesInTransition": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"virtualNetworks": [
|
||||||
|
{
|
||||||
|
"resourceRef": "/virtualNetworks/fcfc99f9-50ce-4644-8a47-a23711c3b704"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"networkVirtualizationEnabled": "True"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nextLink": ""
|
||||||
|
}
|
68
hnv_client/tests/fake/response/logical_subnets.json
Normal file
68
hnv_client/tests/fake/response/logical_subnets.json
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"resourceId": "{uniqueString}",
|
||||||
|
"etag": "00000000-0000-0000-0000-000000000000",
|
||||||
|
"instanceId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
|
||||||
|
"tags": {
|
||||||
|
"key": "value"
|
||||||
|
},
|
||||||
|
"resourceMetadata": {
|
||||||
|
"client": "<Insert likely client>",
|
||||||
|
"tenantId": "{subscriptionid}",
|
||||||
|
"groupId": "{groupname}",
|
||||||
|
"name": "{name}",
|
||||||
|
"originalHref": "https://..."
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"provisioningState": "Updating",
|
||||||
|
"ipConfigurations": [],
|
||||||
|
"networkInterfaces": [],
|
||||||
|
"vlanID": "1",
|
||||||
|
"routes": [],
|
||||||
|
"dnsServers": [
|
||||||
|
"10.0.0.1",
|
||||||
|
"10.0.0.2"
|
||||||
|
],
|
||||||
|
"defaultGateways": [
|
||||||
|
"192.168.1.1",
|
||||||
|
"192.168.1.2"
|
||||||
|
],
|
||||||
|
"isPublic": true,
|
||||||
|
"ipPools": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceId": "{uniqueString}",
|
||||||
|
"etag": "00000000-0000-0000-0000-000000000000",
|
||||||
|
"instanceId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
|
||||||
|
"tags": {
|
||||||
|
"key": "value"
|
||||||
|
},
|
||||||
|
"resourceMetadata": {
|
||||||
|
"client": "<Insert likely client>",
|
||||||
|
"tenantId": "{subscriptionid}",
|
||||||
|
"groupId": "{groupname}",
|
||||||
|
"name": "{name}",
|
||||||
|
"originalHref": "https://..."
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"provisioningState": "Succeeded",
|
||||||
|
"ipConfigurations": [],
|
||||||
|
"networkInterfaces": [],
|
||||||
|
"vlanID": "1",
|
||||||
|
"routes": [],
|
||||||
|
"dnsServers": [
|
||||||
|
"10.0.0.1",
|
||||||
|
"10.0.0.2"
|
||||||
|
],
|
||||||
|
"defaultGateways": [
|
||||||
|
"192.168.1.1",
|
||||||
|
"192.168.1.2"
|
||||||
|
],
|
||||||
|
"isPublic": true,
|
||||||
|
"ipPools": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import unittest.mock as mock
|
import unittest.mock as mock
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -24,6 +25,8 @@ from hnv_client import client
|
|||||||
from hnv_client.common import constant
|
from hnv_client.common import constant
|
||||||
from hnv_client.common import exception
|
from hnv_client.common import exception
|
||||||
from hnv_client import config as hnv_config
|
from hnv_client import config as hnv_config
|
||||||
|
from hnv_client.tests.fake import fake_response
|
||||||
|
from hnv_client.tests import utils as test_utils
|
||||||
|
|
||||||
CONFIG = hnv_config.CONFIG
|
CONFIG = hnv_config.CONFIG
|
||||||
|
|
||||||
@ -163,3 +166,52 @@ class TestBaseHNVModel(unittest.TestCase):
|
|||||||
def test_commit_invalid_response(self):
|
def test_commit_invalid_response(self):
|
||||||
self._test_commit(loop_count=1, timeout=False,
|
self._test_commit(loop_count=1, timeout=False,
|
||||||
failed=False, invalid_response=True)
|
failed=False, invalid_response=True)
|
||||||
|
|
||||||
|
|
||||||
|
class TestClient(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self._response = fake_response.FakeResponse()
|
||||||
|
|
||||||
|
def _test_get_resource(self, model, raw_data):
|
||||||
|
with test_utils.LogSnatcher("hnv_client.client") as logging:
|
||||||
|
model.from_raw_data(raw_data)
|
||||||
|
self.assertEqual(logging.output, [])
|
||||||
|
|
||||||
|
def test_logical_networks(self):
|
||||||
|
resources = self._response.logical_networks()
|
||||||
|
for raw_data in resources.get("value", []):
|
||||||
|
self._test_get_resource(model=client.LogicalNetworks,
|
||||||
|
raw_data=raw_data)
|
||||||
|
|
||||||
|
def test_logical_network_structure(self):
|
||||||
|
raw_data = self._response.logical_networks()["value"][0]
|
||||||
|
logical_network = client.LogicalNetworks.from_raw_data(raw_data)
|
||||||
|
|
||||||
|
for logical_subnetwork in logical_network.subnetworks:
|
||||||
|
self.assertIsInstance(logical_subnetwork,
|
||||||
|
client.LogicalSubnetworks)
|
||||||
|
|
||||||
|
for virtual_network in logical_network.virtual_networks:
|
||||||
|
self.assertIsInstance(virtual_network, client.Resource)
|
||||||
|
|
||||||
|
def test_logical_subnets(self):
|
||||||
|
resources = self._response.logical_subnets()
|
||||||
|
for raw_data in resources.get("value", []):
|
||||||
|
self._test_get_resource(model=client.LogicalSubnetworks,
|
||||||
|
raw_data=raw_data)
|
||||||
|
|
||||||
|
def test_logical_subnets_structure(self):
|
||||||
|
raw_data = self._response.logical_subnets()["value"][0]
|
||||||
|
logical_subnetwork = client.LogicalSubnetworks.from_raw_data(raw_data)
|
||||||
|
|
||||||
|
for ip_pool in logical_subnetwork.ip_pools:
|
||||||
|
self.assertIsInstance(ip_pool, client.IPPools)
|
||||||
|
|
||||||
|
def test_ip_pools(self):
|
||||||
|
resources = self._response.ip_pools()
|
||||||
|
for raw_data in resources.get("value", []):
|
||||||
|
raw_data["parentResourceID"] = "{uniqueString}"
|
||||||
|
raw_data["grandParentResourceID"] = "{uniqueString}"
|
||||||
|
self._test_get_resource(model=client.IPPools,
|
||||||
|
raw_data=raw_data)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user