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
Beispiel #28
0
    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