def _create_virtual_server(self, vip): vsName = vip['name'] vsIpAddress = vip['address'] vsPort = vip['protocol_port'] description = vip['description'] serverPort = self._adx_server_port(vsIpAddress, vsPort, vsName) try: vsSeq = (self.slb_factory .create('ArrayOfVirtualServerConfigurationSequence')) vsConfig = (self.slb_factory .create('VirtualServerConfiguration')) vsConfig.virtualServer = serverPort.srvr vsConfig.adminState = True vsConfig.description = description # Work Around to define a value for Enumeration Type vsConfig.predictor = 'ROUND_ROBIN' vsConfig.trackingMode = 'NONE' vsConfig.haMode = 'NOT_CONFIGURED' (vsSeq.VirtualServerConfigurationSequence .append(vsConfig)) (self.slb_service. createVirtualServerWithConfiguration(vsSeq)) except WebFault as e: LOG.error(_("Exception in _create_virtual_server in device driver : %s"), e.message) raise adx_exception.ConfigError(msg=e.message)
def _create_virtual_server_port(self, vip): vsName = vip['name'] vsIpAddress = vip['address'] vsPort = vip['protocol_port'] admin_state_up = vip.get('admin_state_up', True) try: serverPort = self._adx_server_port(vsIpAddress, vsPort, vsName) vsPortSeq = (self.slb_factory.create ('ArrayOfVirtualServerPortConfigurationSequence')) vsPortConfig = (self.slb_factory .create('VirtualServerPortConfiguration')) vsPortConfig.virtualServer = serverPort.srvr vsPortConfig.port = serverPort.port vsPortAdminState = 'ENABLED' if admin_state_up else 'DISABLED' vsPortConfig.adminState = vsPortAdminState session_persistence = vip.get('session_persistence') if session_persistence: sp_type = session_persistence['type'] if sp_type == constants.SESSION_PERSISTENCE_SOURCE_IP: vsPortConfig.enableSticky = True else: error_message = (_('Session Persistence of type %s ' 'not supported')) % (sp_type) LOG.error(error_message) raise adx_exception.UnsupportedFeature(msg=error_message) (vsPortSeq.VirtualServerPortConfigurationSequence .append(vsPortConfig)) (self.slb_service .createVirtualServerPortWithConfiguration(vsPortSeq)) except WebFault as e: raise adx_exception.ConfigError(msg=e.message)
def _unbind_monitor_from_member(self, health_monitor, member): rsIpAddress = member['address'] rsName = rsIpAddress if member.get('name'): rsName = member['name'] rsPort = member['protocol_port'] rsAdminState = 'ENABLED' if member['admin_state_up'] else 'DISABLED' rsRunTimeStatus = 'UNDEFINED' try: rsServerPort = self._adx_server_port(rsIpAddress, rsPort, rsName) realServerPortConfig = (self.slb_factory .create('RealServerPortConfiguration')) realServerPortConfig.serverPort = rsServerPort realServerPortConfig.adminState = rsAdminState realServerPortConfig.runTimeStatus = rsRunTimeStatus realServerPortConfig.portPolicyName = '' realServerPortConfig.enablePeriodicHealthCheck = False rsPortSeq = (self.slb_factory .create('ArrayOfRealServerPortConfigurationSequence')) (rsPortSeq.RealServerPortConfigurationSequence .append(realServerPortConfig)) self.slb_service.setRealServersPortConfiguration(rsPortSeq) except WebFault as e: raise adx_exception.ConfigError(msg=e.message)
def _update_real_server_port_properties(self, new_member, old_member): try: address = new_member['address'] protocol_port = new_member['protocol_port'] new_admin_state_up = new_member.get('admin_state_up') old_admin_state_up = old_member.get('admin_state_up') if new_admin_state_up == old_admin_state_up: return msg = _('Update Admin State to %(admin_state)s') LOG.debug(msg, {'admin_state': new_admin_state_up}) rsServerPort = self._adx_server_port(address, protocol_port) reply = (self.slb_service .getRealServerPortConfiguration(rsServerPort)) rsPortConfSeq = (self.slb_factory.create ('ArrayOfRealServerPortConfigurationSequence')) reply.rsPortConfig.serverPort = rsServerPort rsPortAdminState = 'ENABLED' if not new_admin_state_up: rsPortAdminState = 'DISABLED' reply.rsPortConfig.adminState = rsPortAdminState rsPortConfList = [reply.rsPortConfig] rsPortConfSeq.RealServerPortConfigurationSequence = rsPortConfList LOG.debug(_("Update real server port properties: %s"), rsPortConfSeq) (self.slb_service .setRealServersPortConfiguration(rsPortConfSeq)) except WebFault as e: raise adx_exception.ConfigError(msg=e.message)
def _update_real_server_properties(self, new_member, old_member): try: address = new_member['address'] new_weight = new_member.get('weight') old_weight = old_member.get('weight') if new_weight == old_weight: return msg = _('Update Weight to %(weight)s') LOG.debug(msg % {'weight': new_weight}) rsServer = self._adx_server(address) reply = (self.slb_service .getRealServerConfiguration(rsServer)) rsConfSeq = (self.slb_factory.create ("ArrayOfRealServerConfigurationSequence")) if new_weight: reply.rsConfig.leastConnectionWeight = new_weight rsConfList = [] rsConfList.append(reply.rsConfig) rsConfSeq.RealServerConfigurationSequence = rsConfList LOG.debug(_("Update real server properties: %s"), rsConfSeq) (self.slb_service .setRealServersConfiguration(rsConfSeq)) except WebFault as e: raise adx_exception.ConfigError(msg=e.message)
def ifconfig_e1(self, ip_address, cidr): # Configure route only on e1 try: (network,mask) = cidr.split('/') ifconfig = self.net_factory.create('InterfaceConfig') ifconfig.id.interfaceType = "ETHERNET" ifconfig.id.portString = "1" ifconfig.isRouteOnly = True interfaceConfigSeq = self.net_factory.create( 'ArrayOfInterfaceConfigSequence') interfaceConfigSeq.InterfaceConfigSequence.append(ifconfig) self.net_service.setInterfaceConfig(interfaceConfigSeq) # Configure ip address on e1 ifid = self.net_factory.create('InterfaceID') ipaddrSeq = self.net_factory.create('ArrayOfInterfaceIPAddressSequence') ipaddr = self.net_factory.create('InterfaceIPAddress') ifid.portString = "1" ifid.interfaceType = "ETHERNET" ipaddr.ip = ip_address ipaddr.subnetMaskLength = mask ipaddrSeq.InterfaceIPAddressSequence.append(ipaddr) # Sending operations to the vLb self.net_service.setInterfaceConfig(interfaceConfigSeq) self.net_service.addIPsToInterface(ifid,ipaddrSeq) except WebFault as e: LOG.debug(_('Exception configuring e1 %s'), e) raise adx_exception.ConfigError(msg=e.message)
def delete_health_monitor(self, health_monitor, pool_id): healthMonitorName = health_monitor['id'] if health_monitor.get('name'): healthMonitorName = health_monitor['name'] monitor_type = health_monitor['type'] # Retrieve the members of the pool from pool_id # Unbind health monitor from the members members = self._get_pool_members(pool_id) for member in members: self._unbind_monitor_from_member(health_monitor, member) if monitor_type in [constants.HEALTH_MONITOR_HTTP, constants.HEALTH_MONITOR_HTTPS, constants.HEALTH_MONITOR_TCP]: if not self._does_port_policy_exist(health_monitor): LOG.debug(_('Health Monitor %s does not ' 'exist on the device'), healthMonitorName) return if not self._is_port_policy_in_use(healthMonitorName): try: (self.slb_service .deletePortPolicy(healthMonitorName)) LOG.debug(_('Health Monitor %s ' 'deleted successfully'), healthMonitorName) except WebFault as e: raise adx_exception.ConfigError(msg=e.message) elif monitor_type == constants.HEALTH_MONITOR_PING: m = _('Delete of PING Monitor not supported') LOG.error(m) raise adx_exception.UnsupportedFeature(msg=m)
def delete_pool(self, pool): # Note: Pool cannot be deleted if bound to a vip. # No need to check here. Will be handled in Framework itself pool_id = pool['id'] pool_name = pool['name'] try: serverGroupList = (self.slb_factory .create('ArrayOfStringSequence')) serverGroupList.StringSequence.append(pool_name) (self.slb_service .deleteRealServerGroups(serverGroupList)) except WebFault as e: raise adx_exception.ConfigError(msg=e.message) # Retrieve health monitors # Delete health monitors health_monitors = self._get_health_monitors(pool_id) for health_monitor in health_monitors: self.delete_health_monitor(health_monitor, pool_id) # Retrieve pool members # Delete members members = self._get_pool_members(pool_id) for member in members: self.delete_member(member)
def enable_source_nat(self): try: globalConfig = self.slb_factory.create('GlobalSlbConfiguration') globalConfig.enableSourceNat = True self.slb_service.updateSlbGlobalConfiguration(globalConfig) except WebFault as e: LOG.debug(_('Exception configuring static route %s'), e) raise adx_exception.ConfigError(msg=e.message)
def _delete_port_profile(self, port_profile): protocol_port = port_profile['protocol_port'] try: l4Port = self.slb_factory.create('L4Port') l4Port.NameOrNumber = protocol_port LOG.debug(_('Delete Port Profile: %s'), l4Port) self.slb_service.deletePortProfile(l4Port) except WebFault as e: LOG.debug(_('Exception in Delete Port Profile %s'), e) raise adx_exception.ConfigError(msg=e.message)
def delete_member(self, member): rsPortCount = self._get_server_port_count(member['address'], False) try: rsServerPort = self._adx_server_port(member['address'], member['protocol_port']) self.slb_service.deleteRealServerPort(rsServerPort) # Delete the Real Server # if this is the only port other than default port if rsPortCount <= 2: self.slb_service.deleteRealServer(rsServerPort.srvr) except WebFault as e: raise adx_exception.ConfigError(msg=e.message)
def delete_vip(self, vip): address = vip['address'] port = vip['protocol_port'] vsServerPort = self._adx_server_port(address, port) vipPortCount = self._get_server_port_count(address, True) try: self.slb_service.deleteVirtualServerPort(vsServerPort) except WebFault: pass try: if vipPortCount <= 2: self.slb_service.deleteVirtualServer(vsServerPort.srvr) except WebFault as e: raise adx_exception.ConfigError(msg=e.message)
def create_static_route(self, destIPAddress, networkMask, nexthopIPAddress): try: staticRoute = self.net_factory.create('StaticRoute') staticRouteSeq = self.net_factory.create('ArrayOfStaticRouteSequence') staticRoute.staticRouteType = 'STANDARD' staticRoute.ipVersion = 'IPV4' staticRoute.destIPAddress = destIPAddress staticRoute.networkMaskBits = networkMask staticRoute.nexthopIPAddress = nexthopIPAddress staticRouteSeq.StaticRouteSequence.append(staticRoute) self.net_service.createStaticRoute(staticRouteSeq) except WebFault as e: LOG.debug(_('Exception configuring static route %s'), e) raise adx_exception.ConfigError(msg=e.message)
def _unbind_member_from_vip(self, member, vip): rsIpAddress = member['address'] rsName = rsIpAddress if member.get('name'): rsName = member['name'] rsPort = member['protocol_port'] vsIpAddress = vip['address'] vsPort = vip['protocol_port'] vsName = vip['name'] try: vsServerPort = self._adx_server_port(vsIpAddress, vsPort, vsName) rsServerPort = self._adx_server_port(rsIpAddress, rsPort, rsName) (self.slb_service .unbindRealServerPortFromVipPort(vsServerPort, rsServerPort)) except WebFault as e: raise adx_exception.ConfigError(msg=e.message)
def _bind_member_to_vip(self, member, vip): rsIpAddress = member['address'] rsName = rsIpAddress if member.get('name'): rsName = member['name'] rsPort = member['protocol_port'] # IceHouse: vip address is no longer in the vip datastructure, we need # to fetch the address from the ipallocations table from neutron #vsIpAddress = vip['address'] vsIpAddress = self._get_vip_address(vip['port_id']) vsPort = vip['protocol_port'] vsName = vip['name'] try: vsServerPort = self._adx_server_port(vsIpAddress, vsPort, vsName) rsServerPort = self._adx_server_port(rsIpAddress, rsPort, rsName) (self.slb_service .bindRealServerPortToVipPort(vsServerPort, rsServerPort)) except WebFault as e: raise adx_exception.ConfigError(msg=e.message)
def _set_predictor_on_virtual_server(self, vip, lb_method): # TODO: Source_IP not supported, not implemented try: server = self._adx_server(self._get_vip_address(vip['port_id']), vip['name']) predictorMethodConfiguration = (self.slb_factory.create ('PredictorMethodConfiguration')) predictor = ADX_PREDICTOR_MAP.get(lb_method) if predictor: predictorMethodConfiguration.predictor = predictor else: error_message = (_('Load Balancing Method/Predictor %s ' 'not supported')) % (lb_method) LOG.error(error_message) raise adx_exception.UnsupportedFeature(msg=error_message) (self.slb_service .setPredictorOnVirtualServer(server, predictorMethodConfiguration)) except WebFault as e: raise adx_exception.ConfigError(msg=e.message)
def _create_real_server_port(self, member): address = member['address'] port = member['protocol_port'] admin_state_up = member['admin_state_up'] name = address if member.get('name'): name = member['name'] is_backup = member.get('is_backup', False) try: # Create Port Profile if it is not a standard port if port not in ADX_STANDARD_PORTS: port_profile = dict() port_profile['protocol_port'] = port self._create_port_profile(port_profile) rsServerPort = self._adx_server_port(address, port, name) rsPortSeq = (self.slb_factory .create('ArrayOfRealServerPortConfigurationSequence')) rsPortConfig = (self.slb_factory .create('RealServerPortConfiguration')) rsPortConfig.serverPort = rsServerPort rsAdminState = 'ENABLED' if admin_state_up else 'DISABLED' rsPortConfig.adminState = rsAdminState if 'max_connections' in member: rsPortConfig.maxConnection = member['max_connections'] rsPortConfig.isBackup = is_backup # Work Around to define a value for Enumeration Type rsPortConfig.runTimeStatus = 'UNDEFINED' (rsPortSeq.RealServerPortConfigurationSequence .append(rsPortConfig)) self.slb_service.createRealServerPortWithConfiguration(rsPortSeq) except WebFault as e: raise adx_exception.ConfigError(msg=e.message)
def write_mem(self): try: self.sys_service_client.service.writeConfig() except Exception as e: raise adx_exception.ConfigError(msg=e.message)
def update_vip(self, old_vip, new_vip): # As per the API specification, # following properties on VIP can be updated. # name - Not Supported in ADX # description - Not applicable in ADX # pool_id # session_persistence # connection_limit - Not Applicable in ADX # admin_state_up - Supported in ADX # TODO: implement change name vsIpAddress = new_vip['address'] vsPort = new_vip['protocol_port'] vsName = new_vip['name'] vsServerPort = self._adx_server_port(vsIpAddress, vsPort, vsName) old_admin_state_up = old_vip.get('admin_state_up') new_admin_state_up = new_vip.get('admin_state_up') if new_admin_state_up != old_admin_state_up: msg = _('Update Admin State to %(state)s') LOG.debug(msg, {'state': new_admin_state_up}) try: if new_admin_state_up: (self.slb_service .enableVirtualServerPort(vsServerPort)) else: (self.slb_service .disableVirtualServerPort(vsServerPort)) except WebFault as e: raise adx_exception.ConfigError(msg=e.message) old_session_persistence = old_vip.get('session_persistence') new_session_persistence = new_vip.get('session_persistence') if new_session_persistence != old_session_persistence: LOG.debug(_('Update Session Persistence')) if new_session_persistence is None: try: (self.slb_service .disableStickyOnVirtualServerPort(vsServerPort)) except WebFault as e: raise adx_exception.ConfigError(msg=e.message) else: type = new_vip['session_persistence']['type'] if type == constants.SESSION_PERSISTENCE_SOURCE_IP: try: (self.slb_service .enableStickyOnVirtualServerPort(vsServerPort)) except WebFault as e: raise adx_exception.ConfigError(msg=e.message) else: error_message = (_('Session Persistence of type %s ' 'not supported')) % (type) LOG.error(error_message) raise adx_exception.UnsupportedFeature(msg=error_message) # Retrieve the lb_method from the pool and set it on vip old_pool_id = old_vip['pool_id'] new_pool_id = new_vip['pool_id'] if old_pool_id != new_pool_id: # Pool has been updated pool = self._get_pool(new_pool_id) lb_method = pool['lb_method'] self._set_predictor_on_virtual_server(new_vip, lb_method) # Retrieve the pool members of old_pool_id # Unbind the members from vip members = self._get_pool_members(old_pool_id) for member in members: self._unbind_member_from_vip(member, new_vip) # Retrieve the members of new_pool_id # Bind the members to vip members = self._get_pool_members(new_pool_id) for member in members: self._bind_member_to_vip(member, new_vip)
def _create_update_port_policy(self, health_monitor, is_create=True): # TODO: State (Enable/Disable) does not work name = health_monitor['id'] monitor_type = health_monitor['type'] delay = health_monitor['delay'] self._validate_delay(monitor_type, delay) max_retries = health_monitor['max_retries'] self._validate_max_retries(max_retries) if monitor_type in [constants.HEALTH_MONITOR_HTTP, constants.HEALTH_MONITOR_HTTPS, constants.HEALTH_MONITOR_TCP]: portPolicy = self.slb_factory.create('PortPolicy') l4Port = self.slb_factory.create('L4Port') if monitor_type == constants.HEALTH_MONITOR_HTTP: portPolicy.name = name l4Port.NameOrNumber = (ADX_PROTOCOL_MAP .get(constants.PROTOCOL_HTTP)) portPolicy.port = l4Port portPolicy.protocol = (ADX_PROTOCOL_MAP .get(constants.PROTOCOL_HTTP)) portPolicy.l4Check = False elif monitor_type == constants.HEALTH_MONITOR_HTTPS: portPolicy.name = name l4Port.NameOrNumber = (ADX_PROTOCOL_MAP .get(constants.PROTOCOL_HTTPS)) portPolicy.port = l4Port portPolicy.protocol = (ADX_PROTOCOL_MAP .get(constants.PROTOCOL_HTTPS)) portPolicy.l4Check = False elif monitor_type == constants.HEALTH_MONITOR_TCP: # TCP Monitor portPolicy.name = name portPolicy.l4Check = True # Setting Protocol and Port to HTTP # so that this can be bound to a Real Server Port l4Port.NameOrNumber = (ADX_PROTOCOL_MAP .get(constants.PROTOCOL_HTTP)) portPolicy.port = l4Port portPolicy.protocol = (ADX_PROTOCOL_MAP .get(constants.PROTOCOL_HTTP)) portPolicy.keepAliveInterval = delay portPolicy.numRetries = max_retries http_method = 'GET' url_path = '/' expected_codes = '200' ''' Not needed in IceHouse if 'http_method' in health_monitor: http_method = health_monitor['http_method'] if 'url_path' in health_monitor: LOG.debug('~~~~~~~~~~~ HERE!!!! ~~~~~~~~') url_path = health_monitor['url_path'] ''' http_method = health_monitor['http_method'] url_path = health_monitor['url_path'] start_status_codes = [] end_status_codes = [] if 'expected_codes' in health_monitor: expected_codes = health_monitor['expected_codes'] # parse the expected codes. # Format:"200, 201, 300-400, 400-410" for code in map(lambda x: x.strip(' '), expected_codes.split(',')): if '-' in code: codeRange = map(lambda x: x.strip(' '), code.split('-')) start_status_codes.append(int(codeRange[0])) end_status_codes.append(int(codeRange[1])) else: start_status_codes.append(int(code)) end_status_codes.append(int(code)) if monitor_type == constants.HEALTH_MONITOR_HTTP: httpPortPolicy = (self.slb_factory .create('HttpPortPolicy')) urlHealthCheck = (self.slb_factory .create('URLHealthCheck')) startCodes = (self.slb_factory .create('ArrayOfunsignedIntSequence')) endCodes = (self.slb_factory .create('ArrayOfunsignedIntSequence')) startCodes.unsignedIntSequence = start_status_codes endCodes.unsignedIntSequence = end_status_codes urlHealthCheck.url = http_method + ' ' + url_path urlHealthCheck.statusCodeRangeStart = startCodes urlHealthCheck.statusCodeRangeEnd = endCodes httpPortPolicy.urlStatusCodeInfo = urlHealthCheck httpPortPolicy.healthCheckType = 'SIMPLE' portPolicy.httpPolInfo = httpPortPolicy elif monitor_type == constants.HEALTH_MONITOR_TCP: httpPortPolicy = (self.slb_factory .create('HttpPortPolicy')) urlHealthCheck = (self.slb_factory .create('URLHealthCheck')) urlHealthCheck.url = 'HEAD /' httpPortPolicy.urlStatusCodeInfo = urlHealthCheck httpPortPolicy.healthCheckType = 'SIMPLE' portPolicy.httpPolInfo = httpPortPolicy elif monitor_type == constants.HEALTH_MONITOR_HTTPS: sslPortPolicy = (self.slb_factory .create('HttpPortPolicy')) urlHealthCheck = (self.slb_factory .create('URLHealthCheck')) startCodes = (self.slb_factory .create('ArrayOfunsignedIntSequence')) endCodes = (self.slb_factory .create('ArrayOfunsignedIntSequence')) urlHealthCheck.url = http_method + ' ' + url_path urlHealthCheck.statusCodeRangeStart = startCodes urlHealthCheck.statusCodeRangeEnd = endCodes sslPortPolicy.urlStatusCodeInfo = urlHealthCheck sslPortPolicy.healthCheckType = 'SIMPLE' portPolicy.sslPolInfo = sslPortPolicy LOG.debug('Health Monitor %s' % portPolicy) try: if is_create: self.slb_service.createPortPolicy(portPolicy) else: self.slb_service.updatePortPolicy(portPolicy) except WebFault as e: LOG.error(_('Error in create/update port policy %s'), e) raise adx_exception.ConfigError(msg=e.message)