def _get_netscaler_renameloadbalancer_task(self, loadBalancerId, newLoadBalancerId, loadBalancer): if not all([loadBalancerId, newLoadBalancerId, loadBalancer ]) or not "name" in loadBalancer: raise ImplementationError("programming error") existing_name = NitroUtils.get_lbvservername_from_loadbalancerid( loadBalancerId) new_name = NitroUtils.get_lbvservername_from_loadbalancerid( newLoadBalancerId) task = {} task["name"] = existing_name task["type"] = "lbvserver" task["operation"] = "RENAME" obj = {} obj["name"] = existing_name obj["newname"] = new_name task["state"] = obj return task
def _get_netscaler_node_from_service_and_servicebinding(self, loadBalancerId, loadBalancer, service, servicebinding): node = LBNodeState(self.lbresource) service_name = service["name"] node.id = NitroUtils.get_nodeid_from_servicename(loadBalancerId, service_name) if "ipaddress" in service and service["ipaddress"]: ipaddress = service["ipaddress"] ipaddress = ipaddress.encode('ascii', 'ignore') node.address = ipaddress if "port" in service and service["port"]: port = service["port"] port = str(port) node.port = port if "svrstate" in service and service["svrstate"]: svrstate = service["svrstate"] node.condition = NitroUtils.get_condition_from_svrstate(svrstate) node.status = NitroUtils.get_nodestatus_from_svrstate(svrstate) if "weight" in servicebinding and servicebinding["weight"]: weight = servicebinding["weight"] node.weight = str(weight) self.logger.debug("returned node is: %s" % node) return node
def _get_netscaler_service_from_node(self, loadBalancerId, loadBalancer, nodeId, node): service_obj = {} for key in node: self.logger.debug("Examining key \"%s\" of node object" % key) if key == "_properties": continue if key == "id": service_obj["name"] = NitroUtils.get_servicename_from_nodeid(loadBalancerId, nodeId) continue if key == "address": service_obj["ip"] = node.address continue if key == "port": service_obj["port"] = node.port continue if loadBalancer: servicetype = NitroUtils.get_servicetype_from_protocol(loadBalancer.protocol) servicetype = NitroUtils.get_decrypted_version_of_servicetype(servicetype) service_obj["servicetype"] = servicetype return service_obj
def _get_netscaler_updatenode_protocol_task(self, loadBalancerId, loadBalancer, node, newLoadBalancerId): servicename = NitroUtils.get_servicename_from_nodeid( loadBalancerId, node.id) if not "protocol" in loadBalancer: return None lbprotocol = loadBalancer.protocol servicetype = NitroUtils.get_servicetype_from_protocol(lbprotocol) servicetype = NitroUtils.get_decrypted_version_of_servicetype( servicetype) service = {} service["name"] = servicename service["protocol"] = servicetype task = {} task["name"] = servicename task["type"] = "service" task["operation"] = "UPDATE" task["state"] = service return task
def _get_netscaler_updateloadbalancer_task(self, loadBalancerId, loadBalancer, newLoadBalancerId=None): task_list = [] self.logger.debug("About to get lbvserver state") if newLoadBalancerId: lbvserver_name = NitroUtils.get_lbvservername_from_loadbalancerid( newLoadBalancerId) else: lbvserver_name = NitroUtils.get_lbvservername_from_loadbalancerid( loadBalancerId) lbvserver = self._get_lbvserver_state(lbvserver_name, loadBalancer) lbvserver = self._adjust_lbvserver_state_for_update( loadBalancerId, lbvserver) if not lbvserver: return None if len(lbvserver.keys()) <= 1: """ There is no field to update on the lbvserver, so no need for an update task """ return None task = {} task["type"] = "lbvserver" task["name"] = lbvserver_name task["operation"] = "UPDATE" task["state"] = lbvserver return task
def add_LoadBalancer(self, newLoadBalancer, tenant_id): self.logger.debug("adding loadbalancer %s" % repr(newLoadBalancer)) existing_ids = self.db.get_tenant_loadBalancers(tenant_id) loadBalancerId = str(NitroUtils.generate_loadbalancerid(existing_ids)) self._setup_nitrowrapper(tenant_id, loadBalancerId) self._allocate_loadBalancer_vips(newLoadBalancer, tenant_id, loadBalancerId) internalLoadBalancer = newLoadBalancer internalLoadBalancerId = NitroUtils.get_internal_loadBalancerId( tenant_id, loadBalancerId, internalLoadBalancer) self._add_LoadBalancerInternal(internalLoadBalancerId, internalLoadBalancer) loadBalancer = self._get_LoadBalancerInternal(internalLoadBalancerId) loadBalancer.id = loadBalancerId loadBalancer.protocol = internalLoadBalancer.protocol loadBalancer.algorithm = internalLoadBalancer.algorithm self.db.create_loadBalancer(tenant_id, loadBalancer) self.db.fill_loadBalancer_vips_info(tenant_id, loadBalancer.id, loadBalancer) return loadBalancer
def _get_netscaler_servicenames_of_loadBalancer(self, loadBalancerId): """ We need to get the servicebindings to know the names of the services from this loadBalancer """ servicebindings = NitroUtils.get_servicebindings_of_loadBalancer( self, loadBalancerId) servicenames = NitroUtils.get_servicenames_from_servicebindings( servicebindings) return servicenames
def get_netscaler_addnodes_tasks(self, loadBalancerId, loadBalancer, nodes, existing_ids=[]): """ Preconditions: A. The lbvserver object must have the following attributes for this method to work: 1. name 2. service_type B. The lb_algorithm must contain a non empty value """ total_nodes = len(existing_ids) + len(nodes) self.logger.debug("existing node ids are: %s" % str(existing_ids)) if total_nodes > MAX_NODES_PER_LOADBALANCER: raise OverLimitException("Number of nodes exceeds maximum of %s allowed per load balancer" % MAX_NODES_PER_LOADBALANCER) task_list = [] for node in nodes: if not "id" in node: operation = "ADD" nodeid = NitroUtils.generate_nodeid(existing_ids) existing_ids.append(nodeid) node.id = str(nodeid) else: operation = "UPDATE" task = self._get_netscaler_addservice_task(loadBalancerId, loadBalancer, node.id, node) task["operation"] = operation task_list.append(task) task = self.get_netscaler_addservicebinding_task(loadBalancerId, loadBalancer, node.id, node) task_list.append(task) service_name = NitroUtils.get_servicename_from_nodeid(loadBalancerId, node.id) if operation == "ADD": task = self._get_netscaler_addservicestatus_task(loadBalancerId, loadBalancer, node.id, node) task = self._get_netscaler_addmonitorbinding_task(loadBalancerId, loadBalancer, node) if operation == "UPDATE": task = self._get_netscaler_updateservicestatus_task(loadBalancerId, loadBalancer, node.id, node) if task: task_list.append(task) return task_list
def _get_netscaler_node_currentcondition(self, loadBalancerId, loadBalancer, nodeId): service_name = NitroUtils.get_servicename_from_nodeid(loadBalancerId, nodeId) service = self.nitrowrapper.get_netscaler_entity("service", service_name) svrstate = service["svrstate"] current_condition = NitroUtils.get_condition_from_svrstate(svrstate) return current_condition
def _get_netscaler_monitorbinding_from_healthmonitor( self, loadBalancerId, node, healthMonitor): monitor_name = NitroUtils.get_monitorname_from_loadBalancerId( loadBalancerId) service_name = NitroUtils.get_servicename_from_nodeid( loadBalancerId, node.id) monitor_binding = {} monitor_binding["monitorname"] = monitor_name monitor_binding["servicename"] = service_name return monitor_binding
def update_LoadBalancer(self, loadBalancerId, updatedLoadBalancer, tenant_id): self._setup_nitrowrapper(tenant_id, loadBalancerId) dbLoadBalancer = self._get_new_loadBalancer_object() dbLoadBalancer = self.db.fill_loadBalancer_object( tenant_id, loadBalancerId, dbLoadBalancer) if not dbLoadBalancer: raise ItemNotFoundException( "No loadBalancer with id %s was found" % loadBalancerId) if dbLoadBalancer.status == "DELETED": raise ImmutableEntityException( "loadBalancer with id %s was deleted and cannot be updated" % loadBalancerId) internalLoadBalancer = updatedLoadBalancer internalLoadBalancerId = NitroUtils.get_internal_loadBalancerId( tenant_id, loadBalancerId, dbLoadBalancer) self._update_LoadBalancerInternal(internalLoadBalancerId, internalLoadBalancer) dbLoadBalancer = self.db.update_loadBalancer(tenant_id, loadBalancerId, internalLoadBalancer) internalLoadBalancerId = NitroUtils.get_internal_loadBalancerId( tenant_id, loadBalancerId, dbLoadBalancer) loadBalancer = self._get_LoadBalancerInternal(internalLoadBalancerId) loadBalancer.id = dbLoadBalancer.id loadBalancer.protocol = dbLoadBalancer.protocol loadBalancer.algorithm = dbLoadBalancer.algorithm loadBalancer.created = dbLoadBalancer.created loadBalancer.updated = dbLoadBalancer.updated self.db.fill_loadBalancer_vips_info(tenant_id, loadBalancer.id, loadBalancer) self.logger.debug( "Successfully completed update loadbalancer operation on the adapter" ) return loadBalancer
def get_netscaler_removeservicebinding_task(self, loadBalancerId, loadBalancer, nodeId): lbvserver_name = NitroUtils.get_lbvservername_from_loadbalancerid(loadBalancerId) servicename = NitroUtils.get_servicename_from_nodeid(loadBalancerId, nodeId) args = "servicename:" + servicename args += "," args += "name:" + lbvserver_name task = {} task["type"] = "lbvserver_service_binding" task["name"] = lbvserver_name + "?args=" + args task["operation"] = "REMOVE" task["state"] = None return task
def get_netscaler_removeboundservices_tasks(self, loadBalancerId, loadBalancer): """I need first to get the list of service names""" task_list = [] task = self.get_netscaler_getservicebindings_task(loadBalancerId, loadBalancer) task_list.append(task) completed_tasks = self.nitrowrapper.process_netscaler_task_list(task_list) servicebindings = NitroTasks.extract_servicebindings_from_task_list(completed_tasks) if not servicebindings: return task_list """ We form a new task list to remove the service bindings and the services """ nodeIds = [] for binding in servicebindings: servicename = self._get_netscaler_servicename_from_servicebinding(loadBalancerId, loadBalancer, binding) nodeId = NitroUtils.get_nodeid_from_servicename(loadBalancerId, servicename) nodeIds.append(nodeId) task_list = [] tasks = self._get_netscaler_removeservicebindings_tasks(loadBalancerId, loadBalancer, nodeIds) task_list.extend(tasks) tasks = self._get_netscaler_removeservices_tasks(loadBalancerId, loadBalancer, nodeIds) task_list.extend(tasks) return task_list
def update_LBNode(self, loadBalancerId, nodeId, lbnode, tenant_id): self._setup_nitrowrapper(tenant_id, loadBalancerId) """" dbLoadBalancer = self._get_new_loadBalancer_object() dbLoadBalancer = self.db.fill_loadBalancer_object(tenant_id, loadBalancerId, dbLoadBalancer) if not dbLoadBalancer: raise ItemNotFoundException("No loadBalancer with id %s was found" % loadBalancerId) if dbLoadBalancer.status == "DELETED": raise ImmutableEntityException("loadBalancer with id %s was deleted and cannot be updated" % loadBalancerId) """ loadBalancer = self.lbadapter.get_LoadBalancer(loadBalancerId, tenant_id) internal_loadBalancerId = NitroUtils.get_internal_loadBalancerId(tenant_id, loadBalancerId, loadBalancer) lbnode.id = nodeId lbnode = self._update_LBNodeInternal(internal_loadBalancerId, loadBalancer, nodeId, lbnode) self.db.update_loadBalancer_updatetime(tenant_id, loadBalancerId) return lbnode
def _nitro_disable_netscaler_entity(self, resource_type, resource_state, _retries=0): if _retries == MAX_NITRO_RETRIES: self.logger.debug("Failed to connect to Netscaler after several retries") raise ImplementationErrorException("The Load Balancing Service is misbehaving." + " Please contact support") path_prefix = self.conn.path url = path_prefix headers = {'Content-Type':'application/x-www-form-urlencoded'} params_part = "\"params\":{\"action\":\"disable\"}" sessionid_part = "\"sessionid\":\"" + self.conn.sessionid + "\"" self.logger.debug("disable task state: " + str(resource_state)) entity_part = NitroUtils.get_entity_payload_from_dictobj(resource_type, resource_state) self.logger.debug("disable body: " + str(entity_part)) body= "{" + params_part + "," + sessionid_part + "," + entity_part + "}" body = "object=" + body status, response = self._nitro_perform_http_request('POST', url, headers, body) if status == "SESSION_EXPIRED": """ login sessionid to Netscaler expired. Relogin and retry the call""" self.nitro_login() return self._nitro_disable_netscaler_entity(resource_type, resource_state, _retries + 1)
def get_netscaler_removemonitorbinding_task(self, loadBalancerId, loadBalancer, nodeId): monitor_name = NitroUtils.get_monitorname_from_loadBalancerId( loadBalancerId) servicename = NitroUtils.get_servicename_from_nodeid( loadBalancerId, nodeId) args = "servicename:" + servicename task = {} task["type"] = "lbmonitor_service_binding" task["name"] = monitor_name + "?args=" + args task["operation"] = "REMOVE" task["state"] = None return task
def _get_lbvserver_state(self, lbvserver_name, loadBalancer): lbvserver = {} lbvserver["name"] = lbvserver_name for key in loadBalancer: self.logger.debug("Examining key \"%s\" of loadBalancer payload" % key) if key == "_properties": continue if key == "protocol": lbvserver[ "servicetype"] = NitroUtils.get_servicetype_from_protocol( loadBalancer.protocol) """ XXX - We also need to modify the protocol of all the services of this lbvserver!! """ continue if key == "port": lbvserver["port"] = loadBalancer.port continue if key == "algorithm": algorithm = loadBalancer.algorithm lbvserver["lbmethod"] = NitroUtils.get_lbmethod_from_algorithm( algorithm) continue if key == "virtualIps": virtualIps = loadBalancer.virtualIps self._set_netscaler_lbvserver_vipaddress(lbvserver, virtualIps) continue if key == "sessionPersistence": sessionPersistence = loadBalancer.sessionPersistence self._set_netscaler_lbvserver_persistencetype( lbvserver, sessionPersistence) continue if self._process_loadBalancer_extensions(loadBalancer, key, lbvserver): continue return lbvserver
def _get_netscaler_getservicebinding_task(self, loadBalancerId, loadBalancer, nodeId): self.logger.debug("loadBalancer Id is: %s" % loadBalancerId) self.logger.debug("node Id is: %s" % nodeId) lbvserver_name = NitroUtils.get_lbvservername_from_loadbalancerid(loadBalancerId) service_name = NitroUtils.get_servicename_from_nodeid(loadBalancerId, nodeId) args = "servicename:" + service_name task = {} task["type"] = "lbvserver_service_binding" task["name"] = lbvserver_name + "?filter=" + args task["operation"] = "GET" task["state"] = None return task
def list_LBNodes(self, tenant_id, loadBalancerId): self._setup_nitrowrapper(tenant_id, loadBalancerId) loadBalancer = self.lbadapter.get_LoadBalancer(loadBalancerId, tenant_id) internal_loadBalancerId = NitroUtils.get_internal_loadBalancerId(tenant_id, loadBalancerId, loadBalancer) return self._list_LBNodesInternal(internal_loadBalancerId, loadBalancer)
def allocate_virtualIP(self, viptype, tenant_id, loadBalancerId): if not viptype in self.vip_pools.keys(): self._configure_pool(viptype) all_vips = self.vip_pools[viptype] allocated_vips = self.db.get_allocated_vips(viptype) allocated_addresses = [vip["address"] for vip in allocated_vips] allocated_vipids = [vip["id"] for vip in allocated_vips] for vip in all_vips: """ Check if this is an individual entry or a range """ if self._is_range(vip): self.logger.debug("already allocated vips are: %s" % str(allocated_addresses)) free_vip = self._get_free_vip_in_range(vip, allocated_addresses) if free_vip: break continue else: if vip in allocated_addresses: continue free_vip = vip break else: raise OutOfVirtualIpsException( "Out of virtual IPs. Please contact support so they can make available more virtual IPs for use." ) vip_id = NitroUtils.generate_vipid(allocated_vipids) version = IP(free_vip).version() if version == 4: vip_version = "IPV4" elif version == 6: vip_version = "IPV6" else: self.logger.debug( "Allocated IP address %s doesn't seem to be IPV4 or IPV6 !!" % free_vip) raise ServiceUnavailableException( "Internal error.Please contact support") self.db.allocate_vip(vip_id, free_vip, viptype, vip_version, tenant_id, loadBalancerId) self.logger.debug( "Allocated VIP: address=%s ipVersion=%s type=%s id=%s" % (free_vip, vip_version, viptype, vip_id)) return free_vip
def _get_netscaler_servicebinding_from_node(self, loadBalancerId, loadBalancer, nodeId, node): service_binding_obj = {} lbvserver_name = NitroUtils.get_lbvservername_from_loadbalancerid(loadBalancerId) service_name = NitroUtils.get_servicename_from_nodeid(loadBalancerId, nodeId) service_binding_obj["name"] = lbvserver_name service_binding_obj["servicename"] = service_name if "weight" in node and node.weight != 1 : if not loadBalancer.algorithm.startswith("WEIGHTED_"): raise BadRequestException("validation fault", "invalid object", "LB algorithm in use doesn't allow for weighted nodes") service_binding_obj["weight"] = node["weight"] return service_binding_obj
def get_netscaler_getservices_tasks(self, loadBalancerId, loadBalancer, servicebindings): task_list = [] for binding in servicebindings: servicename = binding["servicename"] nodeId = NitroUtils.get_nodeid_from_servicename(loadBalancerId, servicename) task = self._get_netscaler_getservice_task(loadBalancerId, loadBalancer, nodeId) task_list.append(task) return task_list
def _get_netscaler_removeservice_task(self, loadBalancerId, loadBalancer, nodeId): servicename = NitroUtils.get_servicename_from_nodeid(loadBalancerId, nodeId) task = {} task["type"] = "service" task["name"] = servicename task["operation"] = "REMOVE" task["state"] = None return task
def get_netscaler_getservicebindings_task(self, loadBalancerId, loadBalancer): lbvserver_name = NitroUtils.get_lbvservername_from_loadbalancerid(loadBalancerId) task = {} task["type"] = "lbvserver_service_binding" task["name"] = lbvserver_name task["operation"] = "GET" task["state"] = None return task
def get_LBNode(self, tenant_id, loadBalancerId, nodeId): self._setup_nitrowrapper(tenant_id, loadBalancerId) loadBalancer = self.lbadapter.get_LoadBalancer(loadBalancerId, tenant_id) internal_loadBalancerId = NitroUtils.get_internal_loadBalancerId(tenant_id, loadBalancerId, loadBalancer) lbnode = self._get_LBNodeInternal(internal_loadBalancerId, loadBalancer, nodeId) return lbnode
def remove_LBNode(self, loadBalancerId, nodeId, tenant_id): self._setup_nitrowrapper(tenant_id, loadBalancerId) loadBalancer = self.lbadapter.get_LoadBalancer(loadBalancerId, tenant_id) internal_loadBalancerId = NitroUtils.get_internal_loadBalancerId(tenant_id, loadBalancerId, loadBalancer) self._remove_LBNodeInternal(internal_loadBalancerId, loadBalancer, nodeId) self.db.update_loadBalancer_updatetime(tenant_id, loadBalancerId)
def _set_netscaler_lbvserver_persistencetype(self, lbvserver, sessionPersistence): if "persistenceType" in sessionPersistence: lbvserver[ "persistencetype"] = NitroUtils.get_nspersistencetype_from_persistencetype( sessionPersistence.persistenceType) if self.extensions_enabled: if "timeout" in sessionPersistence: lbvserver["timeout"] = sessionPersistence.timeout
def get_netscaler_getlbvserver_task(loadBalancerId): lbvserver_name = NitroUtils.get_lbvservername_from_loadbalancerid( loadBalancerId) task = {} task["type"] = "lbvserver" task["name"] = lbvserver_name task["operation"] = "GET" task["state"] = None return task
def _get_netscaler_removeloadbalancer_task(self, loadBalancerId): lbvserver_name = NitroUtils.get_lbvservername_from_loadbalancerid( loadBalancerId) task = {} task["type"] = "lbvserver" task["name"] = lbvserver_name task["operation"] = "REMOVE" task["state"] = None return task
def _process_loadBalancer_extensions(self, loadBalancer, key, lbvserver): if not self.extensions_enabled: return False if key == "sureConnect": sureConnect = loadBalancer.sureConnect lbvserver["sc"] = NitroUtils.get_nssureconnect_from_sureconnect( sureConnect) return True return False