class L7PolicyBuilder(object): """Class supports CRUD for L7 policies and rules Handles both L7 policy and L7 rules for these events: - create l7 policy - delete l7 policy """ def __init__(self, event, f5_l7policy): self.event = event self.f5_l7policy = f5_l7policy self.helper = BigIPResourceHelper(ResourceType.l7policy) if event == 'DELETE_L7POLICY': # both rules and policies handled by same method self.execute = self.delete else: # create and update event for both rules and polices self.execute = self.create def create(self, bigip): LOG.debug("L7PolicyBuilder: create") if self.helper.exists(bigip, name=self.f5_l7policy['name'], partition=self.f5_l7policy['partition']): self.helper.update(bigip, self.f5_l7policy) else: self.helper.create(bigip, self.f5_l7policy) def delete(self, bigip): LOG.debug("L7PolicyBuilder: delete") self.helper.delete( bigip, self.f5_l7policy['name'], self.f5_l7policy['partition'])
class LoadBalancerServiceBuilder(object): """Create loadbalancer related objects on BIG-IPs Handles requests to create and delete LBaaS v2 tenant partition folders on one or more BIG-IP systems. """ def __init__(self): self.folder_helper = BigIPResourceHelper(ResourceType.folder) def create_partition(self, service, bigips): """Create tenant partition on set of BIG-IPs. Creates a partition if it is not named "Common". :param service: Dictionary which contains a both a listener and load balancer definition. :param bigips: Array of BigIP class instances to create Listener. """ folder = ServiceModelAdapter.get_partition(service) if folder != "Common": for bigip in bigips: self.folder_helper.create(bigip, folder) def delete_partition(self, service, bigips): """Deletes partition from a set of BIG-IP systems. Deletes partition if it is not named "Common". :param service: Dictionary which contains a load balancer definition. :param bigips: Array of BigIP class instances to delete partition. """ folder = ServiceModelAdapter.get_partition(service) if folder != "Common": for bigip in bigips: self.folder_helper.delete(bigip, name=folder["name"]) def prep_service(self, service, bigips): """Prepares for LBaaS service request by creating partition. Creates partition, if not Common, and sets partition name on service loadbalancer. :param service: service object for request. :param bigips: Array of BigIP class instances to delete partition. """ # create partition if not Common self.create_partition(service, bigips) # set partition name on loadbalancer object ServiceModelAdapter.set_partition(service)
class PoolServiceBuilder(object): """Create LBaaS v2 pools and related objects on BIG-IP®s. Handles requests to create, update, delete LBaaS v2 pools, health monitors, and members on one or more BIG-IP® systems. """ def __init__(self, service_adapter): self.service_adapter = service_adapter self.http_mon_helper = BigIPResourceHelper(ResourceType.http_monitor) self.https_mon_helper = BigIPResourceHelper(ResourceType.https_monitor) self.tcp_mon_helper = BigIPResourceHelper(ResourceType.tcp_monitor) self.ping_mon_helper = BigIPResourceHelper(ResourceType.ping_monitor) self.pool_helper = BigIPResourceHelper(ResourceType.pool) self.node_helper = BigIPResourceHelper(ResourceType.node) def create_pool(self, service, bigips): """Create a pool on set of BIG-IP®s. Creates a BIG-IP® pool to represent an LBaaS pool object. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigips: Array of BigIP class instances to create pool. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: self.pool_helper.create(bigip, pool) def delete_pool(self, service, bigips): """Delete a pool on set of BIG-IP®s. Deletes a BIG-IP® pool defined by LBaaS pool object. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigips: Array of BigIP class instances to delete pool. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: self.pool_helper.delete(bigip, name=pool["name"], partition=pool["partition"]) def update_pool(self, service, bigips): """Update BIG-IP® pool. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigips: Array of BigIP class instances to create pool. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: self.pool_helper.update(bigip, pool) def create_healthmonitor(self, service, bigips): # create member hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) pool = self.service_adapter.get_pool(service) for bigip in bigips: hm_helper.create(bigip, hm) # update pool with new health monitor self.pool_helper.update(bigip, pool) def delete_healthmonitor(self, service, bigips): # delete health monitor hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) # update pool pool = self.service_adapter.get_pool(service) pool["monitor"] = "" for bigip in bigips: # need to first remove monitor reference from pool self.pool_helper.update(bigip, pool) # after updating pool, delete monitor hm_helper.delete(bigip, name=hm["name"], partition=hm["partition"]) def update_healthmonitor(self, service, bigips): hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) for bigip in bigips: hm_helper.update(bigip, hm) # Note: can't use BigIPResourceHelper class because members # are created within pool objects. Following member methods # use the F5® SDK directly. def create_member(self, service, bigips): pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) for bigip in bigips: part = pool["partition"] p = self.pool_helper.load(bigip, name=pool["name"], partition=part) m = p.members_s.members member_exists = m.exists(name=urllib.quote(member["name"]), partition=part) if not member_exists: m.create(**member) def delete_member(self, service, bigips): pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) part = pool["partition"] for bigip in bigips: p = self.pool_helper.load(bigip, name=pool["name"], partition=part) m = p.members_s.members member_exists = m.exists(name=urllib.quote(member["name"]), partition=part) if member_exists: m = m.load(name=urllib.quote(member["name"]), partition=part) m.delete() node = self.service_adapter.get_member_node(service) self.node_helper.delete(bigip, name=urllib.quote(node["name"]), partition=node["partition"]) def update_member(self, service, bigips): # TODO(jl) handle state -- SDK enforces at least state=None pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) part = pool["partition"] for bigip in bigips: p = self.pool_helper.load(bigip, name=pool["name"], partition=part) m = p.members_s.members if m.exists(name=urllib.quote(member["name"]), partition=part): m = m.load(name=urllib.quote(member["name"]), partition=part) m.modify(**member) def _get_monitor_helper(self, service): monitor_type = self.service_adapter.get_monitor_type(service) if monitor_type == "HTTPS": hm = self.https_mon_helper elif monitor_type == "TCP": hm = self.tcp_mon_helper elif monitor_type == "PING": hm = self.ping_mon_helper else: hm = self.http_mon_helper return hm
class PoolServiceBuilder(object): """Create LBaaS v2 pools and related objects on BIG-IPs. Handles requests to create, update, delete LBaaS v2 pools, health monitors, and members on one or more BIG-IP systems. """ def __init__(self, service_adapter): self.service_adapter = service_adapter self.http_mon_helper = BigIPResourceHelper(ResourceType.http_monitor) self.https_mon_helper = BigIPResourceHelper(ResourceType.https_monitor) self.tcp_mon_helper = BigIPResourceHelper(ResourceType.tcp_monitor) self.ping_mon_helper = BigIPResourceHelper(ResourceType.ping_monitor) self.pool_helper = BigIPResourceHelper(ResourceType.pool) self.node_helper = BigIPResourceHelper(ResourceType.node) def create_pool(self, service, bigips): """Create a pool on set of BIG-IPs. Creates a BIG-IP pool to represent an LBaaS pool object. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigips: Array of BigIP class instances to create pool. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: self.pool_helper.create(bigip, pool) def delete_pool(self, service, bigips): """Delete a pool on set of BIG-IPs. Deletes a BIG-IP pool defined by LBaaS pool object. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigips: Array of BigIP class instances to delete pool. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: self.pool_helper.delete(bigip, name=pool["name"], partition=pool["partition"]) def update_pool(self, service, bigips): """Update BIG-IP pool. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigips: Array of BigIP class instances to create pool. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: self.pool_helper.update(bigip, pool) def create_healthmonitor(self, service, bigips): # create member hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) pool = self.service_adapter.get_pool(service) for bigip in bigips: hm_helper.create(bigip, hm) # update pool with new health monitor self.pool_helper.update(bigip, pool) def delete_healthmonitor(self, service, bigips): # delete health monitor hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) # update pool pool = self.service_adapter.get_pool(service) pool["monitor"] = "" for bigip in bigips: # need to first remove monitor reference from pool self.pool_helper.update(bigip, pool) # after updating pool, delete monitor hm_helper.delete(bigip, name=hm["name"], partition=hm["partition"]) def update_healthmonitor(self, service, bigips): hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) pool = self.service_adapter.get_pool(service) for bigip in bigips: hm_helper.update(bigip, hm) # update pool with new health monitor self.pool_helper.update(bigip, pool) # Note: can't use BigIPResourceHelper class because members # are created within pool objects. Following member methods # use the F5 SDK directly. def create_member(self, service, bigips): pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) for bigip in bigips: part = pool["partition"] p = self.pool_helper.load(bigip, name=pool["name"], partition=part) m = p.members_s.members m.create(**member) def delete_member(self, service, bigips): pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) part = pool["partition"] for bigip in bigips: p = self.pool_helper.load(bigip, name=pool["name"], partition=part) m = p.members_s.members member_exists = m.exists(name=urllib.quote(member["name"]), partition=part) if member_exists: m = m.load(name=urllib.quote(member["name"]), partition=part) m.delete() try: node = self.service_adapter.get_member_node(service) self.node_helper.delete(bigip, name=urllib.quote(node["name"]), partition=node["partition"]) except HTTPError as err: # Possilbe error if node is shared with another member. # If so, ignore the error. if err.response.status_code == 400: LOG.debug(err.message) else: raise def update_member(self, service, bigips): pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) part = pool["partition"] for bigip in bigips: p = self.pool_helper.load(bigip, name=pool["name"], partition=part) m = p.members_s.members if m.exists(name=urllib.quote(member["name"]), partition=part): m = m.load(name=urllib.quote(member["name"]), partition=part) member.pop("address", None) m.modify(**member) def delete_orphaned_members(self, service, bigips): pool = self.service_adapter.get_pool(service) srv_members = service['members'] part = pool['partition'] for bigip in bigips: p = self.pool_helper.load(bigip, name=pool['name'], partition=part) deployed_members = p.members_s.get_collection() for dm in deployed_members: orphaned = True for sm in srv_members: svc = { "loadbalancer": service["loadbalancer"], "pool": service["pool"], "member": sm } member = self.service_adapter.get_member(svc) if member['name'] == dm.name: orphaned = False if orphaned: node_name = dm.address dm.delete() try: self.node_helper.delete(bigip, name=urllib.quote(node_name), partition=part) except HTTPError as err: # Possilbe error if node is shared with another member. # If so, ignore the error. if err.response.status_code == 400: LOG.debug(err.message) else: raise def _get_monitor_helper(self, service): monitor_type = self.service_adapter.get_monitor_type(service) if monitor_type == "HTTPS": hm = self.https_mon_helper elif monitor_type == "TCP": hm = self.tcp_mon_helper elif monitor_type == "PING": hm = self.ping_mon_helper else: hm = self.http_mon_helper return hm def get_member_status(self, service, bigip, status_keys): """Return status values for a single pool. Status keys to collect are defined as an array of strings in input status_keys. :param service: Has pool and member name/partition :param bigip: BIG-IP to get member status from. :param status_keys: Array of strings that define which status keys to collect. :return: A dict with key/value pairs for each status defined in input status_keys. """ member_status = {} pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) part = pool["partition"] try: p = self.pool_helper.load(bigip, name=pool["name"], partition=part) m = p.members_s.members if m.exists(name=urllib.quote(member["name"]), partition=part): m = m.load(name=urllib.quote(member["name"]), partition=part) member_status = self.pool_helper.collect_stats( m, stat_keys=status_keys) else: LOG.error( "Unable to get member status. " "Member %s does not exist.", member["name"]) except Exception as e: # log error but continue on LOG.error("Error getting member status: %s", e.message) return member_status
class L7PolicyService(object): """Handles requests to create, update, delete L7 policies on BIG-IPs.""" def __init__(self, conf): self.conf = conf self.policy_helper = BigIPResourceHelper(ResourceType.l7policy) self.rule_helper = BigIPResourceHelper(ResourceType.rule) def create_l7policy(self, f5_l7policy, bigips): LOG.debug("L7PolicyService: create_l7policy") error = None for bigip in bigips: try: self.policy_helper.create(bigip, f5_l7policy) error = None except HTTPError as err: status_code = err.response.status_code if status_code == 409: LOG.debug("L7 policy already exists...updating") try: self.policy_helper.update(bigip, f5_l7policy) except Exception as err: error = f5_ex.L7PolicyUpdateException(err.message) else: error = f5_ex.L7PolicyCreationException(err.message) except Exception as err: error = f5_ex.L7PolicyCreationException(err.message) if error: LOG.error("L7 policy creation error: %s" % error.message) return error def delete_l7policy(self, f5_l7policy, bigips): LOG.debug("L7PolicyService:delete_l7policy") error = False for bigip in bigips: try: self.policy_helper.delete(bigip, f5_l7policy['name'], f5_l7policy['partition']) except HTTPError as err: status_code = err.response.status_code if status_code == 404: LOG.warn("Deleting L7 policy failed...not found: %s", err.message) elif status_code == 400: LOG.debug( "Deleting L7 policy failed...unknown " "client error: %s", err.message) error = f5_ex.L7PolicyDeleteException(err.message) else: error = f5_ex.L7PolicyDeleteException(err.message) except Exception as err: LOG.exception(err) error = f5_ex.L7PolicyDeleteException(err.message) if error: LOG.error("L7 Policy deletion error: %s", error.message) return error def build_policy(self, l7policy, lbaas_service): # build data structure for service adapter input LOG.debug("L7PolicyService: service") import pprint # LOG.debug(pprint.pformat(lbaas_service.service_object, indent=4)) LOG.debug("L7PolicyService: l7policy") # LOG.debug(pprint.pformat(l7policy, indent=4)) l7policy_adapter = L7PolicyServiceAdapter(self.conf) os_policies = { 'l7rules': [], 'l7policies': [], 'f5_policy': {}, 'iRules': [] } # get all policies and rules for listener referenced by this policy listener = lbaas_service.get_listener(l7policy['listener_id']) for policy_id in listener['l7_policies']: policy = lbaas_service.get_l7policy(policy_id['id']) if policy: os_policies['l7policies'].append(policy) for rule in policy['rules']: l7rule = lbaas_service.get_l7rule(rule['id']) if l7rule: os_policies['l7rules'].append(l7rule) if os_policies['l7policies']: os_policies['f5_policy'] = l7policy_adapter.translate(os_policies) if getattr(l7policy_adapter, 'iRules', None): os_policies['iRules'] = l7policy_adapter.iRules LOG.debug(pprint.pformat(os_policies, indent=2)) return os_policies def create_irule(self, irules, bigips): LOG.debug("L7PolicyService: create_iRule") error = None for bigip in bigips: for rule in irules: try: self.rule_helper.create(bigip, rule) except HTTPError as err: status_code = err.response.status_code if status_code == 409: LOG.debug( "L7 rule (REGEX irule) already exists...updating") try: self.rule_helper.update(bigip, rule) except Exception as err: error = f5_ex.L7PolicyUpdateException(err.message) else: error = f5_ex.L7PolicyCreationException(err.message) except Exception as err: error = f5_ex.L7PolicyCreationException(err.message) if error: LOG.error("L7 rule (REGEX irule) creation error: %s" % error.message) return error def delete_irule(self, delete_irules, bigips): LOG.debug("L7PolicyService:delete_iRule") error = False for bigip in bigips: for rule in delete_irules: try: self.rule_helper.delete(bigip, name=rule.get('name'), partition=rule.get('partition')) except HTTPError as err: status_code = err.response.status_code if status_code == 404: LOG.warn( "Deleting L7 policy (iRule) " + "failed...not found: %s", err.message) elif status_code == 400: LOG.debug( "Deleting L7 policy (iRule) failed...unknown " "client error: %s", err.message) error = f5_ex.L7PolicyDeleteException(err.message) else: error = f5_ex.L7PolicyDeleteException(err.message) except Exception as err: LOG.exception(err) error = f5_ex.L7PolicyDeleteException(err.message) if error: LOG.error("L7 Policy (iRule) deletion error: %s", error.message) return error
class PoolServiceBuilder(object): """Create LBaaS v2 pools and related objects on BIG-IPs. Handles requests to create, update, delete LBaaS v2 pools, health monitors, and members on one or more BIG-IP systems. """ def __init__(self, service_adapter): self.service_adapter = service_adapter self.http_mon_helper = BigIPResourceHelper(ResourceType.http_monitor) self.https_mon_helper = BigIPResourceHelper(ResourceType.https_monitor) self.tcp_mon_helper = BigIPResourceHelper(ResourceType.tcp_monitor) self.ping_mon_helper = BigIPResourceHelper(ResourceType.ping_monitor) self.pool_helper = BigIPResourceHelper(ResourceType.pool) self.node_helper = BigIPResourceHelper(ResourceType.node) def create_pool(self, service, bigips): """Create a pool on set of BIG-IPs. Creates a BIG-IP pool to represent an LBaaS pool object. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigips: Array of BigIP class instances to create pool. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: self.pool_helper.create(bigip, pool) def delete_pool(self, service, bigips): """Delete a pool on set of BIG-IPs. Deletes a BIG-IP pool defined by LBaaS pool object. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigips: Array of BigIP class instances to delete pool. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: self.pool_helper.delete(bigip, name=pool["name"], partition=pool["partition"]) def update_pool(self, service, bigips): """Update BIG-IP pool. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigips: Array of BigIP class instances to create pool. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: self.pool_helper.update(bigip, pool) def create_healthmonitor(self, service, bigips): # create member hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) pool = self.service_adapter.get_pool(service) for bigip in bigips: hm_helper.create(bigip, hm) # update pool with new health monitor self.pool_helper.update(bigip, pool) def delete_healthmonitor(self, service, bigips): # delete health monitor hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) # update pool pool = self.service_adapter.get_pool(service) pool["monitor"] = "" for bigip in bigips: # need to first remove monitor reference from pool self.pool_helper.update(bigip, pool) # after updating pool, delete monitor hm_helper.delete(bigip, name=hm["name"], partition=hm["partition"]) def update_healthmonitor(self, service, bigips): hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) pool = self.service_adapter.get_pool(service) for bigip in bigips: hm_helper.update(bigip, hm) # update pool with new health monitor self.pool_helper.update(bigip, pool) # Note: can't use BigIPResourceHelper class because members # are created within pool objects. Following member methods # use the F5 SDK directly. def create_member(self, service, bigips): pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) for bigip in bigips: part = pool["partition"] p = self.pool_helper.load(bigip, name=pool["name"], partition=part) m = p.members_s.members m.create(**member) def delete_member(self, service, bigips): pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) part = pool["partition"] for bigip in bigips: p = self.pool_helper.load(bigip, name=pool["name"], partition=part) m = p.members_s.members member_exists = m.exists(name=urllib.quote(member["name"]), partition=part) if member_exists: m = m.load(name=urllib.quote(member["name"]), partition=part) m.delete() try: node = self.service_adapter.get_member_node(service) self.node_helper.delete(bigip, name=urllib.quote(node["name"]), partition=node["partition"]) except HTTPError as err: # Possilbe error if node is shared with another member. # If so, ignore the error. if err.response.status_code == 400: LOG.debug(err.message) else: raise def update_member(self, service, bigips): pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) part = pool["partition"] for bigip in bigips: p = self.pool_helper.load(bigip, name=pool["name"], partition=part) m = p.members_s.members if m.exists(name=urllib.quote(member["name"]), partition=part): m = m.load(name=urllib.quote(member["name"]), partition=part) member.pop("address", None) m.modify(**member) def delete_orphaned_members(self, service, bigips): pool = self.service_adapter.get_pool(service) srv_members = service['members'] part = pool['partition'] for bigip in bigips: p = self.pool_helper.load(bigip, name=pool['name'], partition=part) deployed_members = p.members_s.get_collection() for dm in deployed_members: orphaned = True for sm in srv_members: svc = {"loadbalancer": service["loadbalancer"], "pool": service["pool"], "member": sm} member = self.service_adapter.get_member(svc) if member['name'] == dm.name: orphaned = False if orphaned: node_name = dm.address dm.delete() try: self.node_helper.delete(bigip, name=urllib.quote(node_name), partition=part) except HTTPError as err: # Possilbe error if node is shared with another member. # If so, ignore the error. if err.response.status_code == 400: LOG.debug(err.message) else: raise def _get_monitor_helper(self, service): monitor_type = self.service_adapter.get_monitor_type(service) if monitor_type == "HTTPS": hm = self.https_mon_helper elif monitor_type == "TCP": hm = self.tcp_mon_helper elif monitor_type == "PING": hm = self.ping_mon_helper else: hm = self.http_mon_helper return hm def get_member_status(self, service, bigip, status_keys): """Return status values for a single pool. Status keys to collect are defined as an array of strings in input status_keys. :param service: Has pool and member name/partition :param bigip: BIG-IP to get member status from. :param status_keys: Array of strings that define which status keys to collect. :return: A dict with key/value pairs for each status defined in input status_keys. """ member_status = {} pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) part = pool["partition"] try: p = self.pool_helper.load(bigip, name=pool["name"], partition=part) m = p.members_s.members if m.exists(name=urllib.quote(member["name"]), partition=part): m = m.load(name=urllib.quote(member["name"]), partition=part) member_status = self.pool_helper.collect_stats( m, stat_keys=status_keys) else: LOG.error("Unable to get member status. " "Member %s does not exist.", member["name"]) except Exception as e: # log error but continue on LOG.error("Error getting member status: %s", e.message) return member_status
class PoolServiceBuilder(object): """Create LBaaS v2 pools and related objects on BIG-IPs. Handles requests to create, update, delete LBaaS v2 pools, health monitors, and members on one or more BIG-IP systems. """ def __init__(self, service_adapter): self.service_adapter = service_adapter self.http_mon_helper = BigIPResourceHelper(ResourceType.http_monitor) self.https_mon_helper = BigIPResourceHelper(ResourceType.https_monitor) self.tcp_mon_helper = BigIPResourceHelper(ResourceType.tcp_monitor) self.ping_mon_helper = BigIPResourceHelper(ResourceType.ping_monitor) self.pool_helper = BigIPResourceHelper(ResourceType.pool) self.node_helper = BigIPResourceHelper(ResourceType.node) def create_pool(self, service, bigips): """Create a pool on set of BIG-IPs. Creates a BIG-IP pool to represent an LBaaS pool object. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigips: Array of BigIP class instances to create Listener. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: try: self.pool_helper.create(bigip, pool) except HTTPError as err: LOG.error("Error creating pool %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (pool["name"], bigip.device_name, err.response.status_code, err.message)) def delete_pool(self, service, bigips): """Delete a pool on set of BIG-IPs. Deletes a BIG-IP pool defined by LBaaS pool object. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigips: Array of BigIP class instances to delete pool. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: try: self.pool_helper.delete(bigip, name=pool["name"], partition=pool["partition"]) except HTTPError as err: LOG.error("Error deleting pool %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (pool["name"], bigip.device_name, err.response.status_code, err.message)) def update_pool(self, service, bigips): """Update BIG-IP pool. :param service: Dictionary which contains a both a pool and load balancer definition. :param bigip: Array of BigIP class instances to create Listener. """ pool = self.service_adapter.get_pool(service) for bigip in bigips: try: self.pool_helper.update(bigip, pool) except HTTPError as err: LOG.error("Error updating pool %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (pool["name"], bigip.device_name, err.response.status_code, err.message)) def create_healthmonitor(self, service, bigips): # create member hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) for bigip in bigips: try: hm_helper.create(bigip, hm) except HTTPError as err: LOG.error("Error creating health monitor %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (hm["name"], bigip.device_name, err.response.status_code, err.message)) # update pool with new health monitor pool = self.service_adapter.get_pool(service) for bigip in bigips: self.pool_helper.update(bigip, pool) def delete_healthmonitor(self, service, bigips): # delete health monitor hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) # update pool pool = self.service_adapter.get_pool(service) pool["monitor"] = "" for bigip in bigips: # need to first remove monitor reference from pool try: self.pool_helper.update(bigip, pool) except HTTPError as err: LOG.error("Error updating pool %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (pool["name"], bigip.device_name, err.response.status_code, err.message)) try: hm_helper.delete(bigip, name=hm["name"], partition=hm["partition"]) except HTTPError as err: LOG.error("Error deleting health monitor %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (hm["name"], bigip.device_name, err.response.status_code, err.message)) def update_healthmonitor(self, service, bigips): hm = self.service_adapter.get_healthmonitor(service) hm_helper = self._get_monitor_helper(service) for bigip in bigips: try: hm_helper.delete(bigip, name=hm["name"], partition=hm["partition"]) except HTTPError as err: LOG.error("Error updating health monitor %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (hm["name"], bigip.device_name, err.response.status_code, err.message)) # Note: can't use BigIPResourceHelper class because members # are created within pool objects. Following member methods # use the F5 SDK directly. def create_member(self, service, bigips): pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) for bigip in bigips: part = pool["partition"] try: p = self.pool_helper.load(bigip, name=pool["name"], partition=part) except HTTPError as err: LOG.error("Error loading pool %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (pool["name"], bigip.device_name, err.response.status_code, err.message)) continue m = p.members_s.members try: member_exists = m.exists(name=member["name"], partition=part) except HTTPError as err: LOG.error("Error checking if member %s exists on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (member["name"], bigip.device_name, err.response.status_code, err.message)) continue if not member_exists: try: m.create(**member) except HTTPError as err: LOG.error("Error creating member %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (member["name"], bigip.device_name, err.response.status_code, err.message)) def delete_member(self, service, bigips): pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) part = pool["partition"] for bigip in bigips: try: p = self.pool_helper.load(bigip, name=pool["name"], partition=part) except HTTPError as err: LOG.error("Error loading pool %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (pool["name"], bigip.device_name, err.response.status_code, err.message)) continue m = p.members_s.members try: member_exists = m.exists(name=member["name"], partition=part) except HTTPError as err: LOG.error("Error checking if member %s exists on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (member["name"], bigip.device_name, err.response.status_code, err.message)) continue if member_exists: try: m = m.load(name=member["name"], partition=part) except HTTPError as err: LOG.error("Error loading member %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (member["name"], bigip.device_name, err.response.status_code, err.message)) continue try: m.delete() node = self.service_adapter.get_member_node(service) self.node_helper.delete(bigip, name=node["name"], partition=node["partition"]) except HTTPError as err: LOG.error("Error deleting member %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (member["name"], bigip.device_name, err.response.status_code, err.message)) def update_member(self, service, bigips): # TODO(jl) handle state -- SDK enforces at least state=None pool = self.service_adapter.get_pool(service) member = self.service_adapter.get_member(service) part = pool["partition"] for bigip in bigips: try: p = self.pool_helper.load(bigip, name=pool["name"], partition=part) except HTTPError as err: LOG.error("Error loading pool %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (pool["name"], bigip.device_name, err.response.status_code, err.message)) continue m = p.members_s.members try: member_exists = m.exists(name=member["name"], partition=part) except HTTPError as err: LOG.error("Error checking if member %s exists on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (member["name"], bigip.device_name, err.response.status_code, err.message)) continue if member_exists: try: m = m.load(name=member["name"], partition=part) except HTTPError as err: LOG.error("Error loading member %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (member["name"], bigip.device_name, err.response.status_code, err.message)) continue try: m.update(**member) except HTTPError as err: LOG.error("Error updating member %s on BIG-IP %s. " "Repsponse status code: %s. Response " "message: %s." % (member["name"], bigip.device_name, err.response.status_code, err.message)) def _get_monitor_helper(self, service): monitor_type = self.service_adapter.get_monitor_type(service) if monitor_type == "HTTPS": hm = self.https_mon_helper elif monitor_type == "TCP": hm = self.tcp_mon_helper elif monitor_type == "PING": hm = self.ping_mon_helper else: hm = self.http_mon_helper return hm