diff --git a/vmware_nsxlib/tests/unit/v3/test_constants.py b/vmware_nsxlib/tests/unit/v3/test_constants.py index 286c461c..b0feaba6 100644 --- a/vmware_nsxlib/tests/unit/v3/test_constants.py +++ b/vmware_nsxlib/tests/unit/v3/test_constants.py @@ -192,3 +192,103 @@ FAKE_IP_SET = { "192.168.1.8", "192.168.4.8/24"] } + +FAKE_APPLICATION_PROFILE_UUID = uuidutils.generate_uuid() +FAKE_APPLICATION_PROFILE = { + "resource_type": "LoadBalancerHttpProfile", + "description": "my http profile", + "id": FAKE_APPLICATION_PROFILE_UUID, + "display_name": "httpprofile1", + "ntlm": False, + "request_header_size": 1024, + "http_redirect_to_https": False, + "idle_timeout": 1800, + "x_forwarded_for": "INSERT", + "_create_user": "admin", + "_create_time": 1493834124218, + "_last_modified_user": "admin", + "_last_modified_time": 1493834124218, + "_system_owned": False, + "_revision": 0 +} + +FAKE_PERSISTENCE_PROFILE_UUID = uuidutils.generate_uuid() +FAKE_PERSISTENCE_PROFILE = { + "resource_type": "LoadBalancerCookiePersistenceProfile", + "description": "cookie persistence", + "id": FAKE_PERSISTENCE_PROFILE_UUID, + "display_name": "cookiePersistence", + "cookie_mode": "INSERT", + "cookie_garble": True, + "cookie_fallback": True, + "cookie_name": "ABC", + "_create_user": "admin", + "_create_time": 1493837413804, + "_last_modified_user": "admin", + "_last_modified_time": 1493837413804, + "_system_owned": False, + "_revision": 0 +} + +FAKE_CLIENT_SSL_PROFILE_UUID = uuidutils.generate_uuid() +FAKE_CLIENT_SSL_PROFILE = { + "display_name": "clientSslProfile1", + "description": "client ssl profile", + "id": FAKE_CLIENT_SSL_PROFILE_UUID, + "prefer_server_ciphers": False, + "session_cache_enabled": False, + "session_cache_timeout": 300 +} + +FAKE_SERVER_SSL_PROFILE_UUID = uuidutils.generate_uuid() +FAKE_SERVER_SSL_PROFILE = { + "display_name": "serverSslProfile1", + "description": "server ssl profile", + "id": FAKE_SERVER_SSL_PROFILE_UUID, + "session_cache_enabled": False +} + +FAKE_MONITOR_UUID = uuidutils.generate_uuid() +FAKE_MONITOR = { + "display_name": "httpmonitor1", + "description": "my http monitor", + "id": FAKE_MONITOR_UUID, + "resource_type": "LoadBalancerHttpMonitor", + "interval": 5, + "rise_count": 3, + "fall_count": 3, + "timeout": 15, + "request_url": "/", + "request_method": "GET", + "monitor_port": "80" +} + +FAKE_POOL_UUID = uuidutils.generate_uuid() +FAKE_POOL = { + "display_name": "httppool1", + "description": "my http pool", + "id": FAKE_POOL_UUID, + "algorithm": "ROUND_ROBIN", +} + +FAKE_VIRTUAL_SERVER_UUID = uuidutils.generate_uuid() +FAKE_VIRTUAL_SERVER = { + "display_name": "httpvirtualserver1", + "description": "my http virtual server", + "id": FAKE_VIRTUAL_SERVER_UUID, + "enabled": True, + "port": "80", + "ip_protocol": "TCP", +} + +FAKE_SERVICE_UUID = uuidutils.generate_uuid() +FAKE_SERVICE = { + "display_name": "my LB web service1", + "description": "my LB web service", + "id": FAKE_SERVICE_UUID, + "enabled": True, + "attachment": { + "target_id": FAKE_ROUTER_UUID, + "target_type": "LogicalRouter" + } +} diff --git a/vmware_nsxlib/tests/unit/v3/test_load_balancer.py b/vmware_nsxlib/tests/unit/v3/test_load_balancer.py new file mode 100644 index 00000000..b548d101 --- /dev/null +++ b/vmware_nsxlib/tests/unit/v3/test_load_balancer.py @@ -0,0 +1,354 @@ +# Copyright 2017 VMware, Inc. +# All Rights Reserved +# +# 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. +# + +import mock + +from vmware_nsxlib.tests.unit.v3 import nsxlib_testcase +from vmware_nsxlib.tests.unit.v3 import test_constants as consts +from vmware_nsxlib.v3 import load_balancer + + +app_profile_types = load_balancer.ApplicationProfileTypes +app_profiles = [app_profile_types.HTTP, + app_profile_types.FAST_TCP, + app_profile_types.FAST_UDP] +per_profile_types = load_balancer.PersistenceProfileTypes +per_profiles = [per_profile_types.COOKIE, per_profile_types.SOURCE_IP] +monitor_types = load_balancer.MonitorTypes +monitors = [monitor_types.HTTP, monitor_types.HTTPS, monitor_types.ICMP, + monitor_types.PASSIVE, monitor_types.TCP, monitor_types.UDP] + +tags = [ + { + 'scope': 'os-project-id', + 'tag': 'project-1' + }, + { + 'scope': 'os-api-version', + 'tag': '2.1.1.0' + } +] + + +class TestApplicationProfile(nsxlib_testcase.NsxClientTestCase): + + def test_create_application_profiles(self): + fake_profile = consts.FAKE_APPLICATION_PROFILE.copy() + for profile_type in app_profiles: + body = { + 'display_name': fake_profile['display_name'], + 'description': fake_profile['description'], + 'resource_type': profile_type, + 'tags': tags + } + with mock.patch.object(self.nsxlib.client, 'create') as create: + self.nsxlib.load_balancer.application_profile.create( + display_name=body['display_name'], + description=body['description'], + resource_type=body['resource_type'], + tags=tags) + create.assert_called_with('loadbalancer/application-profiles', + body) + + def test_list_application_profiles(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + self.nsxlib.load_balancer.application_profile.list() + get.assert_called_with('loadbalancer/application-profiles') + + def test_get_application_profile(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + fake_profile = consts.FAKE_APPLICATION_PROFILE.copy() + self.nsxlib.load_balancer.application_profile.get( + fake_profile['id']) + get.assert_called_with( + 'loadbalancer/application-profiles/%s' % fake_profile['id']) + + def test_delete_application_profile(self): + with mock.patch.object(self.nsxlib.client, 'delete') as delete: + fake_profile = consts.FAKE_APPLICATION_PROFILE.copy() + self.nsxlib.load_balancer.application_profile.delete( + fake_profile['id']) + delete.assert_called_with( + 'loadbalancer/application-profiles/%s' % fake_profile['id']) + + +class TestPersistenceProfile(nsxlib_testcase.NsxClientTestCase): + + def test_create_persistence_profiles(self): + fake_profile = consts.FAKE_PERSISTENCE_PROFILE.copy() + for profile_type in per_profiles: + body = { + 'display_name': fake_profile['display_name'], + 'description': fake_profile['description'], + 'resource_type': profile_type, + 'tags': tags + } + with mock.patch.object(self.nsxlib.client, 'create') as create: + self.nsxlib.load_balancer.persistence_profile.create( + body['display_name'], body['description'], tags, + body['resource_type']) + create.assert_called_with('loadbalancer/persistence-profiles', + body) + + def test_list_persistence_profiles(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + self.nsxlib.load_balancer.persistence_profile.list() + get.assert_called_with('loadbalancer/persistence-profiles') + + def test_get_persistence_profile(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + fake_profile = consts.FAKE_APPLICATION_PROFILE.copy() + self.nsxlib.load_balancer.persistence_profile.get( + fake_profile['id']) + get.assert_called_with( + 'loadbalancer/persistence-profiles/%s' % fake_profile['id']) + + def test_delete_persistence_profile(self): + with mock.patch.object(self.nsxlib.client, 'delete') as delete: + fake_profile = consts.FAKE_PERSISTENCE_PROFILE.copy() + self.nsxlib.load_balancer.persistence_profile.delete( + fake_profile['id']) + delete.assert_called_with( + 'loadbalancer/persistence-profiles/%s' % fake_profile['id']) + + +class TestClientSslProfile(nsxlib_testcase.NsxClientTestCase): + + def test_create_client_ssl_profiles(self): + fake_profile = consts.FAKE_CLIENT_SSL_PROFILE.copy() + body = { + 'display_name': fake_profile['display_name'], + 'description': fake_profile['description'], + 'tags': tags + } + with mock.patch.object(self.nsxlib.client, 'create') as create: + self.nsxlib.load_balancer.client_ssl_profile.create( + body['display_name'], body['description'], tags) + create.assert_called_with('loadbalancer/client-ssl-profiles', + body) + + def test_list_client_ssl_profiles(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + self.nsxlib.load_balancer.client_ssl_profile.list() + get.assert_called_with('loadbalancer/client-ssl-profiles') + + def test_get_client_ssl_profile(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + fake_profile = consts.FAKE_CLIENT_SSL_PROFILE.copy() + self.nsxlib.load_balancer.client_ssl_profile.get( + fake_profile['id']) + get.assert_called_with( + 'loadbalancer/client-ssl-profiles/%s' % fake_profile['id']) + + def test_delete_client_ssl_profile(self): + with mock.patch.object(self.nsxlib.client, 'delete') as delete: + fake_profile = consts.FAKE_CLIENT_SSL_PROFILE.copy() + self.nsxlib.load_balancer.client_ssl_profile.delete( + fake_profile['id']) + delete.assert_called_with( + 'loadbalancer/client-ssl-profiles/%s' % fake_profile['id']) + + +class TestServerSslProfile(nsxlib_testcase.NsxClientTestCase): + + def test_create_server_client_ssl_profiles(self): + fake_profile = consts.FAKE_SERVER_SSL_PROFILE.copy() + body = { + 'display_name': fake_profile['display_name'], + 'description': fake_profile['description'], + 'tags': tags + } + with mock.patch.object(self.nsxlib.client, 'create') as create: + self.nsxlib.load_balancer.server_ssh_profile.create( + body['display_name'], body['description'], tags) + create.assert_called_with('loadbalancer/server-ssl-profiles', + body) + + def test_list_server_ssl_profiles(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + self.nsxlib.load_balancer.server_ssh_profile.list() + get.assert_called_with('loadbalancer/server-ssl-profiles') + + def test_get_server_ssl_profile(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + fake_profile = consts.FAKE_SERVER_SSL_PROFILE.copy() + self.nsxlib.load_balancer.server_ssh_profile.get( + fake_profile['id']) + get.assert_called_with( + 'loadbalancer/server-ssl-profiles/%s' % fake_profile['id']) + + def test_delete_server_ssl_profile(self): + with mock.patch.object(self.nsxlib.client, 'delete') as delete: + fake_profile = consts.FAKE_SERVER_SSL_PROFILE.copy() + self.nsxlib.load_balancer.server_ssh_profile.delete( + fake_profile['id']) + delete.assert_called_with( + 'loadbalancer/server-ssl-profiles/%s' % fake_profile['id']) + + +class TestMonitor(nsxlib_testcase.NsxClientTestCase): + + def test_create_monitors(self): + fake_monitor = consts.FAKE_MONITOR.copy() + for monitor_type in monitors: + body = { + 'display_name': fake_monitor['display_name'], + 'description': fake_monitor['description'], + 'resource_type': monitor_type, + 'tags': tags + } + with mock.patch.object(self.nsxlib.client, 'create') as create: + self.nsxlib.load_balancer.monitor.create( + body['display_name'], body['description'], tags, + body['resource_type']) + create.assert_called_with('loadbalancer/monitors', + body) + + def test_list_monitors(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + self.nsxlib.load_balancer.monitor.list() + get.assert_called_with('loadbalancer/monitors') + + def test_get_monitor(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + fake_monitor = consts.FAKE_MONITOR.copy() + self.nsxlib.load_balancer.monitor.get(fake_monitor['id']) + get.assert_called_with( + 'loadbalancer/monitors/%s' % fake_monitor['id']) + + def test_delete_monitor(self): + with mock.patch.object(self.nsxlib.client, 'delete') as delete: + fake_monitor = consts.FAKE_MONITOR.copy() + self.nsxlib.load_balancer.monitor.delete(fake_monitor['id']) + delete.assert_called_with( + 'loadbalancer/monitors/%s' % fake_monitor['id']) + + +class TestPool(nsxlib_testcase.NsxClientTestCase): + + def test_create_pool(self): + fake_pool = consts.FAKE_POOL.copy() + body = { + 'display_name': fake_pool['display_name'], + 'description': fake_pool['description'], + 'algorithm': fake_pool['algorithm'], + 'tags': tags + } + with mock.patch.object(self.nsxlib.client, 'create') as create: + self.nsxlib.load_balancer.pool.create( + body['display_name'], body['description'], tags, + algorithm=body['algorithm']) + create.assert_called_with('loadbalancer/pools', + body) + + def test_list_pools(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + self.nsxlib.load_balancer.pool.list() + get.assert_called_with('loadbalancer/pools') + + def test_get_pool(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + fake_profile = consts.FAKE_POOL.copy() + self.nsxlib.load_balancer.pool.get(fake_profile['id']) + get.assert_called_with( + 'loadbalancer/pools/%s' % fake_profile['id']) + + def test_delete_pool(self): + with mock.patch.object(self.nsxlib.client, 'delete') as delete: + fake_profile = consts.FAKE_POOL.copy() + self.nsxlib.load_balancer.pool.delete(fake_profile['id']) + delete.assert_called_with( + 'loadbalancer/pools/%s' % fake_profile['id']) + + +class TestVirtualServer(nsxlib_testcase.NsxClientTestCase): + + def test_create_virtual_server(self): + fake_virtual_server = consts.FAKE_VIRTUAL_SERVER.copy() + body = { + 'display_name': fake_virtual_server['display_name'], + 'description': fake_virtual_server['description'], + 'ip_protocol': fake_virtual_server['ip_protocol'], + 'port': fake_virtual_server['port'], + 'enabled': fake_virtual_server['enabled'], + 'tags': tags + } + with mock.patch.object(self.nsxlib.client, 'create') as create: + self.nsxlib.load_balancer.virtual_server.create( + body['display_name'], body['description'], tags, + ip_protocol=body['ip_protocol'], port=body['port'], + enabled=body['enabled']) + create.assert_called_with('loadbalancer/virtual-servers', + body) + + def test_list_virtual_servers(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + self.nsxlib.load_balancer.virtual_server.list() + get.assert_called_with('loadbalancer/virtual-servers') + + def test_get_virtual_server(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + fake_virtual_server = consts.FAKE_VIRTUAL_SERVER.copy() + self.nsxlib.load_balancer.virtual_server.get( + fake_virtual_server['id']) + get.assert_called_with( + 'loadbalancer/virtual-servers/%s' % fake_virtual_server['id']) + + def test_delete_virtual_server(self): + with mock.patch.object(self.nsxlib.client, 'delete') as delete: + fake_virtual_server = consts.FAKE_VIRTUAL_SERVER.copy() + self.nsxlib.load_balancer.virtual_server.delete( + fake_virtual_server['id']) + delete.assert_called_with( + 'loadbalancer/virtual-servers/%s' % fake_virtual_server['id']) + + +class TestService(nsxlib_testcase.NsxClientTestCase): + + def test_create_service(self): + fake_service = consts.FAKE_SERVICE.copy() + body = { + 'display_name': fake_service['display_name'], + 'description': fake_service['description'], + 'enabled': fake_service['enabled'], + 'attachment': fake_service['attachment'], + 'tags': tags + } + with mock.patch.object(self.nsxlib.client, 'create') as create: + self.nsxlib.load_balancer.service.create( + body['display_name'], body['description'], tags, + enabled=body['enabled'], attachment=body['attachment']) + create.assert_called_with('loadbalancer/services', + body) + + def test_list_services(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + self.nsxlib.load_balancer.service.list() + get.assert_called_with('loadbalancer/services') + + def test_get_service(self): + with mock.patch.object(self.nsxlib.client, 'get') as get: + fake_service = consts.FAKE_SERVICE.copy() + self.nsxlib.load_balancer.service.get(fake_service['id']) + get.assert_called_with( + 'loadbalancer/services/%s' % fake_service['id']) + + def test_delete_service(self): + with mock.patch.object(self.nsxlib.client, 'delete') as delete: + fake_service = consts.FAKE_SERVICE.copy() + self.nsxlib.load_balancer.service.delete(fake_service['id']) + delete.assert_called_with( + 'loadbalancer/services/%s' % fake_service['id']) diff --git a/vmware_nsxlib/tests/unit/v3/test_utils.py b/vmware_nsxlib/tests/unit/v3/test_utils.py index 30ee893f..342ff3ac 100644 --- a/vmware_nsxlib/tests/unit/v3/test_utils.py +++ b/vmware_nsxlib/tests/unit/v3/test_utils.py @@ -202,3 +202,37 @@ class TestNsxV3Utils(nsxlib_testcase.NsxClientTestCase): {'scope': 'os-project-name', 'tag': 'Z' * 40}] self.assertEqual(sorted(expected, key=lambda x: x.get('tag')), sorted(tags, key=lambda x: x.get('tag'))) + + def test_build_extra_args_positive(self): + extra_args = ['fall_count', 'interval', 'monitor_port', + 'request_body', 'request_method', 'request_url', + 'request_version', 'response_body', + 'response_status', 'rise_count', 'timeout'] + body = {'display_name': 'httpmonitor1', + 'description': 'my http monitor'} + expected = {'display_name': 'httpmonitor1', + 'description': 'my http monitor', + 'interval': 5, + 'rise_count': 3, + 'fall_count': 3} + resp = utils.build_extra_args(body, extra_args, interval=5, + rise_count=3, fall_count=3) + self.assertEqual(resp, expected) + + def test_build_extra_args_negative(self): + extra_args = ['cookie_domain', 'cookie_fallback', 'cookie_garble', + 'cookie_mode', 'cookie_name', 'cookie_path', + 'cookie_time'] + body = {'display_name': 'persistenceprofile1', + 'description': 'my persistence profile', + 'resource_type': 'LoadBalancerCookiePersistenceProfile'} + expected = {'display_name': 'persistenceprofile1', + 'description': 'my persistence profile', + 'resource_type': 'LoadBalancerCookiePersistenceProfile', + 'cookie_mode': 'INSERT', + 'cookie_name': 'ABC', + 'cookie_fallback': True} + resp = utils.build_extra_args(body, extra_args, cookie_mode='INSERT', + cookie_name='ABC', cookie_fallback=True, + bogus='bogus') + self.assertEqual(resp, expected) diff --git a/vmware_nsxlib/v3/__init__.py b/vmware_nsxlib/v3/__init__.py index dd3b7991..b49c8b63 100644 --- a/vmware_nsxlib/v3/__init__.py +++ b/vmware_nsxlib/v3/__init__.py @@ -23,6 +23,7 @@ from vmware_nsxlib.v3 import client from vmware_nsxlib.v3 import cluster from vmware_nsxlib.v3 import core_resources from vmware_nsxlib.v3 import exceptions +from vmware_nsxlib.v3 import load_balancer from vmware_nsxlib.v3 import native_dhcp from vmware_nsxlib.v3 import policy_defs from vmware_nsxlib.v3 import policy_resources @@ -168,6 +169,8 @@ class NsxLib(NsxLibBase): self.client, self.nsxlib_config) self.ip_pool = resources.IpPool( self.client, self.nsxlib_config) + self.load_balancer = load_balancer.LoadBalancer( + self.client, self.nsxlib_config) @property def keepalive_section(self): diff --git a/vmware_nsxlib/v3/load_balancer.py b/vmware_nsxlib/v3/load_balancer.py new file mode 100644 index 00000000..7b8f5fb4 --- /dev/null +++ b/vmware_nsxlib/v3/load_balancer.py @@ -0,0 +1,272 @@ +# Copyright 2017 VMware, Inc. +# All Rights Reserved +# +# 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. + +from vmware_nsxlib.v3 import exceptions as nsxlib_exc +from vmware_nsxlib.v3 import utils + + +class ApplicationProfileTypes(object): + """LoadBalancer Application Profile types""" + + HTTP = "LoadBalancerHttpProfile" + FAST_TCP = "LoadBalancerFastTcpProfile" + FAST_UDP = "LoadBalancerFastUdpProfile" + + +class PersistenceProfileTypes(object): + """LoadBalancer Persistence Profile types""" + + COOKIE = "LoadBalancerCookiePersistenceProfile" + SOURCE_IP = "LoadBalancerSourceIpPersistenceProfile" + + +class MonitorTypes(object): + """LoadBalancer Monitor types""" + + HTTP = "LoadBalancerHttpMonitor" + HTTPS = "LoadBalancerHttpsMonitor" + ICMP = "LoadBalancerIcmpMonitor" + PASSIVE = "LoadBalancerPassiveMonitor" + TCP = "LoadBalancerTcpMonitor" + UDP = "LoadBalancerUdpMonitor" + + +class LoadBalancerBase(utils.NsxLibApiBase): + resource = '' + + @staticmethod + def _build_args(body, display_name=None, description=None, tags=None, + resource_type=None, **kwargs): + if display_name: + body['display_name'] = display_name + if description: + body['description'] = description + if tags: + body['tags'] = tags + if resource_type: + body['resource_type'] = resource_type + body.update(kwargs) + return body + + def create(self, display_name=None, description=None, tags=None, + resource_type=None, **kwargs): + orig_body = {} + body = self._build_args(orig_body, display_name, description, tags, + resource_type, **kwargs) + return self.client.create(self.resource, body) + + def list(self): + return self.client.get(self.resource) + + def get(self, object_id): + object_url = self.resource + '/' + object_id + return self.client.get(object_url) + + def update(self, object_id, display_name=None, description=None, + tags=None, resource_type=None, **kwargs): + object_url = self.resource + '/' + object_id + orig_body = self.client.get(object_url) + body = self._build_args(orig_body, display_name, description, tags, + resource_type, **kwargs) + return self.client.update(object_url, body) + + def delete(self, object_id): + object_url = self.resource + '/' + object_id + return self.client.delete(object_url) + + +class ApplicationProfile(LoadBalancerBase): + resource = 'loadbalancer/application-profiles' + + @staticmethod + def _build_args(body, display_name=None, description=None, tags=None, + resource_type=None, **kwargs): + if display_name: + body['display_name'] = display_name + if description: + body['description'] = description + if tags: + body['tags'] = tags + if resource_type == ApplicationProfileTypes.HTTP: + body['resource_type'] = resource_type + extra_args = ['http_redirect_to', 'http_redirect_to_https', + 'ntlm', 'request_header_size', 'x_forwarded_for', + 'idle_timeout'] + return utils.build_extra_args(body, extra_args, **kwargs) + elif (resource_type == ApplicationProfileTypes.FAST_TCP or + resource_type == ApplicationProfileTypes.FAST_UDP): + body['resource_type'] = resource_type + extra_args = ['flow_mirroring_enabled', 'idle_timeout'] + return utils.build_extra_args(body, extra_args, **kwargs) + else: + raise nsxlib_exc.InvalidInput( + operation='create_application_profile', + arg_val=resource_type, + arg_name='resource_type') + + +class PersistenceProfile(LoadBalancerBase): + resource = 'loadbalancer/persistence-profiles' + + @staticmethod + def _build_args(body, display_name=None, description=None, tags=None, + resource_type=None, **kwargs): + if display_name: + body['display_name'] = display_name + if description: + body['description'] = description + if tags: + body['tags'] = tags + if resource_type == PersistenceProfileTypes.COOKIE: + body['resource_type'] = resource_type + extra_args = ['cookie_domain', 'cookie_fallback', 'cookie_garble', + 'cookie_mode', 'cookie_name', 'cookie_path', + 'cookie_time'] + return utils.build_extra_args(body, extra_args, **kwargs) + elif resource_type == PersistenceProfileTypes.SOURCE_IP: + body['resource_type'] = resource_type + extra_args = ['persistence_mirroring_enabled', 'purge', 'timeout'] + return utils.build_extra_args(body, extra_args, **kwargs) + else: + raise nsxlib_exc.InvalidInput( + operation='create_persistence_profile', + arg_val=resource_type, + arg_name='resource_type') + + +class ClientSslProfile(LoadBalancerBase): + resource = 'loadbalancer/client-ssl-profiles' + + +class ServerSslProfile(LoadBalancerBase): + resource = 'loadbalancer/server-ssl-profiles' + + +class Monitor(LoadBalancerBase): + resource = 'loadbalancer/monitors' + + @staticmethod + def _build_args(body, display_name=None, description=None, tags=None, + resource_type=None, **kwargs): + if display_name: + body['display_name'] = display_name + if description: + body['description'] = description + if tags: + body['tags'] = tags + if resource_type == MonitorTypes.HTTP: + body['resource_type'] = resource_type + extra_args = ['fall_count', 'interval', 'monitor_port', + 'request_body', 'request_method', 'request_url', + 'request_version', 'response_body', + 'response_status', 'rise_count', 'timeout'] + return utils.build_extra_args(body, extra_args, **kwargs) + elif resource_type == MonitorTypes.HTTPS: + body['resource_type'] = resource_type + extra_args = ['authentication_depth', 'ciphers', + 'client_certificate_id', 'fall_count', 'interval', + 'monitor_port', 'protocols', 'request_body', + 'request_method', 'request_url', 'request_version', + 'response_body', 'response_status', 'rise_count', + 'server_auth', 'server_auth_ca_ids', + 'server_auth_crl_ids', 'timeout'] + return utils.build_extra_args(body, extra_args, **kwargs) + elif resource_type == MonitorTypes.ICMP: + body['resource_type'] = resource_type + extra_args = ['data_length', 'fall_count', 'interval', + 'monitor_port', 'rise_count', 'timeout'] + return utils.build_extra_args(body, extra_args, **kwargs) + elif resource_type == MonitorTypes.PASSIVE: + body['resource_type'] = resource_type + extra_args = ['max_fails', 'timeout'] + return utils.build_extra_args(body, extra_args, **kwargs) + elif (resource_type == MonitorTypes.TCP or + resource_type == MonitorTypes.UDP): + body['resource_type'] = resource_type + extra_args = ['fall_count', 'interval', 'monitor_port', 'receive', + 'rise_count', 'send', 'timeout'] + return utils.build_extra_args(body, extra_args, **kwargs) + else: + raise nsxlib_exc.InvalidInput( + operation='create_monitor', + arg_val=resource_type, + arg_name='resource_type') + + +class Pool(LoadBalancerBase): + resource = 'loadbalancer/pools' + + def update_pool_with_members(self, pool_id, members): + object_url = self.resource + '/' + pool_id + body = self.client.get(object_url) + body['members'] = members + return self.client.update(object_url, body) + + +class VirtualServer(LoadBalancerBase): + resource = 'loadbalancer/virtual-servers' + + def update_virtual_server_with_pool(self, virtual_server_id, pool_id): + object_url = self.resource + '/' + virtual_server_id + body = self.client.get(object_url) + body['pool_id'] = pool_id + return self.client.update(object_url, body) + + def update_virtual_server_with_profiles(self, virtual_server_id, + application_profile_id, + persistence_profile_id): + object_url = self.resource + '/' + virtual_server_id + body = self.client.get(object_url) + body['application_profile_id'] = application_profile_id + body['persistence_profile_id'] = persistence_profile_id + return self.client.update(object_url, body) + + def update_virtual_server_with_vip(self, virtual_server_id, vip): + object_url = self.resource + '/' + virtual_server_id + body = self.client.get(object_url) + body['ip_address'] = vip + return self.client.update(object_url, body) + + +class Service(LoadBalancerBase): + resource = 'loadbalancer/services' + + def update_service_with_virtual_servers(self, service_id, + virtual_server_ids): + object_url = self.resource + '/' + service_id + body = self.client.get(object_url) + body['virtual_server_ids'] = virtual_server_ids + return self.client.update(object_url, body) + + def update_service_with_attachment(self, service_id, logical_router_id): + object_url = self.resource + '/' + service_id + body = self.client.get(object_url) + body['attachment'] = {'target_id': logical_router_id, + 'target_type': 'LogicalRouter'} + return self.client.update(object_url, body) + + +class LoadBalancer(object): + """This is the class that have all load balancer resource clients""" + + def __init__(self, client, nsxlib_config=None): + self.service = Service(client, nsxlib_config) + self.virtual_server = VirtualServer(client, nsxlib_config) + self.pool = Pool(client, nsxlib_config) + self.monitor = Monitor(client, nsxlib_config) + self.application_profile = ApplicationProfile(client, nsxlib_config) + self.persistence_profile = PersistenceProfile(client, nsxlib_config) + self.client_ssl_profile = ClientSslProfile(client, nsxlib_config) + self.server_ssh_profile = ServerSslProfile(client, nsxlib_config) diff --git a/vmware_nsxlib/v3/utils.py b/vmware_nsxlib/v3/utils.py index 9f6afd91..1331bdb5 100644 --- a/vmware_nsxlib/v3/utils.py +++ b/vmware_nsxlib/v3/utils.py @@ -127,6 +127,13 @@ def get_name_and_uuid(name, uuid, tag=None, maxlen=80): return name[:maxlen] + short_uuid +def build_extra_args(body, extra_args, **kwargs): + for arg in extra_args: + if arg in kwargs: + body[arg] = kwargs[arg] + return body + + class NsxLibApiBase(object): """Base class for nsxlib api """ def __init__(self, client, nsxlib_config=None):