From b019452af01db22629809b8930357a2ebf6494be Mon Sep 17 00:00:00 2001 From: Alexandru Coman Date: Thu, 9 Mar 2017 14:45:06 +0200 Subject: [PATCH] Add support for load balancer mux --- hnv/client.py | 142 ++++++++++++++++++ hnv/tests/fake/fake_response.py | 4 + .../fake/response/load_balancer_mux.json | 101 +++++++++++++ hnv/tests/test_client.py | 6 + 4 files changed, 253 insertions(+) create mode 100644 hnv/tests/fake/response/load_balancer_mux.json diff --git a/hnv/client.py b/hnv/client.py index bdcad06..c71d496 100644 --- a/hnv/client.py +++ b/hnv/client.py @@ -3046,3 +3046,145 @@ class LoadBalancerManager(_BaseHNVModel): properties["vipIpPools"] = vip_ip_pools return super(LoadBalancerManager, cls).process_raw_data(raw_data) + + +class _Connections(model.Model): + + """Model for connections LoadBalancerMux's sub-model.""" + + credential = model.Field( + name="credential", key="credential", + is_property=False, is_required=False) + """Indicates a reference to a credential resource that can be used to + connect to the device for management purposes. + """ + + credential_type = model.Field( + name="credential_type", key="credentialType", + is_property=False, is_required=False) + """Indicates the type of credential, e.g. X509Certificate or + UsernamePassword. + """ + + management_addresses = model.Field( + name="management_addresses", key="managementAddresses", + is_property=False, is_required=False) + """Indicates the management address used to connect to the server. This is + in the form of an IPv4 IP address, an IPv6 IP address, a DNS name or a flat + (NetBIOS) name. + """ + + protocol = model.Field(name="protocol", key="protocol", + is_property=False, is_required=False) + + port = model.Field(name="port", key="port", + is_property=False, is_required=False) + + @classmethod + def process_raw_data(cls, raw_data): + raw_content = raw_data.get("credential") + if raw_content is not None: + credential_ref = Resource.from_raw_data(raw_content) + raw_data["credential"] = credential_ref + + return super(_Connections, cls).process_raw_data(raw_data) + + +class _PeerRouterConfiguration(model.Model): + + """Model for peer router configuration _RouterConfiguration sub-model.""" + + peer_id = model.Field(name="peer_id", key="id", + is_property=False, is_required=True) + + name = model.Field(name="name", key="routerName", + is_property=False, is_required=True) + """The friendly name of the peer router.""" + + peer_asn = model.Field(name="peer_asn", key="peerASN", + is_property=False, is_required=True) + """The BGP autonomous system number of the peer.""" + + ip_address = model.Field(name="ip_address", key="routerIPAddress", + is_property=False, is_required=False) + """The IPv4 address of the local interface on the Mux from which peering + to BGP will be established.""" + + +class _RouterConfiguration(model.Model): + + """Model for router configuration LoadBalancerMux's sub-model.""" + + local_asn = model.Field( + name="local_asn", key="localASN", + is_property=False, is_required=True, is_read_only=False) + """Is the BGP autonomous system number of the MUX.""" + + peer_router_configurations = model.Field( + name="peer_router_configurations", + key="peerRouterConfigurations", + is_property=False, is_required=True, is_read_only=False) + """The BGP settings the MUX uses to establish and maintain BGP peering + with one or more peers.""" + + @classmethod + def process_raw_data(cls, raw_data): + router_configurations = [] + for raw_content in raw_data.get("peerRouterConfigurations", []): + configuration = _PeerRouterConfiguration.from_raw_data(raw_content) + router_configurations.append(configuration) + raw_data["peerRouterConfigurations"] = router_configurations + + return super(_RouterConfiguration, cls).process_raw_data(raw_data) + + +class LoadBalancerMux(_BaseHNVModel): + + """Model for load balancer mux resource. + + The LoadBalancerMux resource represents a MUX VM deployed in the + Network Controller's stamp. + """ + + connections = model.Field( + name="connections", key="connections", + is_property=True, is_required=False, is_read_only=False) + """Indicates an array of connections that specifies the information + needed to connect to the specific device for the purposes of managing + and controlling the device. + """ + + router_configuration = model.Field( + name="router_configuration", key="routerConfiguration", + is_property=True, is_required=True, is_read_only=False) + """Provides the BGP router configuration to the MUX to ensure it peers + with the datacenter routing infrastructure and properly advertises routes. + """ + + virtual_server = model.Field( + name="virtual_server", key="virtualServer", + is_property=True, is_required=True, is_read_only=False) + """Indicates a reference to the virtualServer resource that + the loadbalancer mux runs on.""" + + @classmethod + def process_raw_data(cls, raw_data): + properties = raw_data.get("properties", {}) + + connections = [] + for connection in properties.get("connections", []): + connection = _Connections.from_raw_data(connection) + connections.append(connection) + properties["connections"] = connections + + raw_content = properties.get("routerConfiguration") + if raw_content is not None: + configuration = _RouterConfiguration.from_raw_data(raw_content) + properties["routerConfiguration"] = configuration + + raw_content = properties.get("virtualServer") + if raw_content is not None: + resource = Resource.from_raw_data(raw_content) + properties["virtualServer"] = resource + + return super(LoadBalancerMux, cls).process_raw_data(raw_data) diff --git a/hnv/tests/fake/fake_response.py b/hnv/tests/fake/fake_response.py index da55e49..37aba7f 100644 --- a/hnv/tests/fake/fake_response.py +++ b/hnv/tests/fake/fake_response.py @@ -129,3 +129,7 @@ class FakeResponse(object): def load_balancer_manager(self): """Fake GET response for load balancer manager.""" return self._load_resource("load_balancer_manager.json") + + def load_balancer_mux(self): + """Fake GET(all) response for load balancer mux.""" + return self._load_resource("load_balancer_mux.json") diff --git a/hnv/tests/fake/response/load_balancer_mux.json b/hnv/tests/fake/response/load_balancer_mux.json new file mode 100644 index 0000000..74a9330 --- /dev/null +++ b/hnv/tests/fake/response/load_balancer_mux.json @@ -0,0 +1,101 @@ +{ + "value": [ + { + "resourceRef": "/loadBalancerMuxes/Mux-0", + "resourceId": "Mux-0", + "etag": "W/\"fac641b5-304d-4578-878f-cb9fe670bbb5\"", + "instanceId": "68070a20-8434-4885-ae8c-eda27618d4ce", + "properties": { + "provisioningState": "Succeeded", + "routerConfiguration": { + "localASN": 2, + "peerRouterConfigurations": [ + { + "routerName": "BGPGateway-0", + "routerIPAddress": "195.171.120.1", + "peerASN": 1, + "id": "860ed1e7-b165-4397-a2bf-d78578feb1c9" + } + ] + }, + "virtualServer": { + "resourceRef": "/virtualServers/8e361faf-e957-4e26-9728-3ab6454543ab" + }, + "connections": [ + { + "managementAddresses": [ + "195.171.120.21", + "hnv-test22" + ], + "credential": { + "resourceRef": "/credentials/hnv-test22-credentials" + }, + "credentialType": "usernamePassword", + "protocol": "tcp", + "port": "2003" + } + ], + "configurationState": { + "status": "Success", + "detailedInfo": [ + { + "source": "SoftwareLoadBalancerManager", + "message": "Loadbalancer Mux is Healthy.", + "code": "Success" + } + ], + "lastUpdatedTime": "2016-06-09T17:21:46.3280587-07:00" + } + } + }, + { + "resourceRef": "/loadBalancerMuxes/Mux-0", + "resourceId": "Mux-0", + "etag": "W/\"fac641b5-304d-4578-878f-cb9fe670bbb5\"", + "instanceId": "68070a20-8434-4885-ae8c-eda27618d4ce", + "properties": { + "provisioningState": "Succeeded", + "routerConfiguration": { + "localASN": 2, + "peerRouterConfigurations": [ + { + "routerName": "BGPGateway-0", + "routerIPAddress": "195.171.120.1", + "peerASN": 1, + "id": "860ed1e7-b165-4397-a2bf-d78578feb1c9" + } + ] + }, + "virtualServer": { + "resourceRef": "/virtualServers/8e361faf-e957-4e26-9728-3ab6454543ab" + }, + "connections": [ + { + "managementAddresses": [ + "195.171.120.21", + "hnv-test22" + ], + "credential": { + "resourceRef": "/credentials/hnv-test22-credentials" + }, + "credentialType": "usernamePassword", + "protocol": "tcp", + "port": "2003" + } + ], + "configurationState": { + "status": "Success", + "detailedInfo": [ + { + "source": "SoftwareLoadBalancerManager", + "message": "Loadbalancer Mux is Healthy.", + "code": "Success" + } + ], + "lastUpdatedTime": "2016-06-09T17:21:46.3280587-07:00" + } + } + } + ], + "nextLink": "" +} diff --git a/hnv/tests/test_client.py b/hnv/tests/test_client.py index 8cfdec4..d87fd05 100644 --- a/hnv/tests/test_client.py +++ b/hnv/tests/test_client.py @@ -400,3 +400,9 @@ class TestClient(unittest.TestCase): raw_data = self._response.load_balancer_manager() self._test_get_resource(model=client.LoadBalancerManager, raw_data=raw_data) + + def test_load_balancer_mux(self): + resources = self._response.load_balancer_mux() + for raw_data in resources.get("value", []): + self._test_get_resource(model=client.LoadBalancerMux, + raw_data=raw_data)