def _get_free_vip_in_range(self, vip_range, allocated_vips): try: make_net = 0 if "/" in vip_range: make_net = 1 ip_list = IP(vip_range, make_net=make_net) except ValueError: self.logger.debug( "Virtual IP range %s specified in configuration file is invalid:" % vip_range) raise ServiceUnavailableException( "Invalid service configuration.Please contact support") if "-" in vip_range: start_address, end_address = vip_range.split('-') else: network_address = ip_list.net() broadcast_address = ip_list.broadcast() """ netmask or CIDR network notation """ start_address = IP(network_address.int() + 1) end_address = IP(broadcast_address.int() - 1) self.logger.debug("VIP range: %s" % vip_range) self.logger.debug(" start address: %s" % str(start_address)) self.logger.debug(" end address: %s" % str(end_address)) address = self._get_free_vip_in_range2(str(start_address), str(end_address), allocated_vips) return address
def _configure_pool(self, viptype, pools_config): if not pools_config: raise LoadBalancerFaultException( "Error in configuring Virtual IPs of type %s" % viptype) for vip_pool in pools_config: if vip_pool["name"].lower() == viptype.lower(): pool_config = vip_pool["config"] break else: raise BadRequestException( "Validation fault", "The object is not valid", "VirtualIP type specified for load balancer is not a valid type" ) ips_str = pool_config["ips"] ips = ips_str.split(",") ips = [ip.strip() for ip in ips] """ validate IP addresses and ranges found in configuration """ for ip in ips: try: IP(ip) except ValueError as msg: self.logger.debug( "Virtual IP range %s specified in configuration file is invalid:%s" % (ip, msg)) raise ServiceUnavailableException( "Invalid service configuration.Please contact support") self.vip_pools[viptype] = ips
def process_netscaler_task_list(self, task_list, _undoflag=True): if not task_list: return None if _undoflag: task_list = self._reorder_task_list(task_list) exception_error = None partial_failure = False completed_tasks = [] for task in task_list: try: self.process_netscaler_task(task, _undoflag) completed_tasks.append(task) except BadRequestException as error: partial_failure = True exception_error = error break except ItemNotFoundException as error: if not "ignore_notfound" in task or not task["ignore_notfound"] : partial_failure = True exception_error = error break except ImplementationErrorException as error: partial_failure = True exception_error = error break except NotImplementedException as error: partial_failure = True exception_error = error break except ItemNotFoundException as error: partial_failure = True exception_error = error break except ServiceUnavailableException as error: """ A problem with Netscaler. We cannot remedy this """ raise error if partial_failure: self.logger.debug("partial error occurred") try: self._netscaler_undo_changes(completed_tasks) except Exception, e: raise ServiceUnavailableException("Catastrophic error. Cannot undo changes made !!") raise exception_error
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 nitro_login(self): headers = {'Content-Type':'application/x-www-form-urlencoded'} body='object={ "login":{"username":"******","password":"******"}}' % (self.conn.user,self.conn.password) url = self.conn.path status, response = self._nitro_perform_http_request('POST', url, headers, body) if status != "SUCCESS": raise ServiceUnavailableException("The Load Balancing Service is currently unavailable. Please contact support") if response["sessionid"]: self.conn.sessionid = response["sessionid"] else: self.logger.debug("Error: Login failed! status code returned by Netscaler =%d" % repr(resp_dict['errorcode'])) raise ServiceUnavailableException("The Load Balancing Service is currently unavailable. Please contact support")
def auth(self, account, token): """ Dev authorization implmentation :param account: account name :param token: auth token :returns: True if authorization is successful, False otherwise """ return True key = 'auth/%s/%s' % (account, token) now = time.time() if self.memcache_client: cached_auth_data = self.memcache_client.get(key) else: cached_auth_data = None if cached_auth_data: start, expiration = cached_auth_data if now - start <= expiration: return True try: with Timeout(self.timeout): """ conn = http_connect(self.auth_host, self.auth_port, 'GET', '/token/%s/%s' % (account, token), ssl=True) """ conn = http_connect(self.auth_host, self.auth_port, 'GET', '/token/%s' % token, ssl=True) resp = conn.getresponse() resp.read() conn.close() if resp.status == 204: validated = float(resp.getheader('x-auth-ttl')) else: validated = False except: self.logger.exception('auth_host: %s' % self.auth_host) self.logger.exception('auth_port: %s' % self.auth_port) self.logger.exception('ERROR with auth') raise ServiceUnavailableException("The Auth Service is currently unavailable. Please try later") if not validated: return False else: val = (now, validated) if self.memcache_client: self.memcache_client.set(key, val, timeout=validated) return True
def SetUp(logger, conf): plugin_config = conf["plugin"] connmanager = NitroConnectionManager(plugin_config, logger) logger.debug("Connection Manager is: %s" % repr(connmanager)) if not connmanager: logger.debug("Error: Setting up adaptor failed") raise ServiceUnavailableException("The Load Balancing Service is currently unavailable. Please contact support") """"No Error occurred""" return CitrixNetScalerLBService(connmanager, conf, logger)
def make_service_call(self, req, env, method_dict, variables): try: req_method = req.method.upper() call_pattern = method_dict[req_method] call_pattern = self.replace_variables(req, call_pattern, variables) self.logger.debug("Call on resource is: %s" % str(call_pattern)) response = eval(call_pattern) except BadRequestException as error: content_type, detail = self.get_error_body(req, error) return HTTPBadRequest(body=detail, content_type=content_type, request=req) except NotImplementedException as error: content_type, detail = self.get_error_body(req, error) return HTTPNotImplemented(body=detail, content_type=content_type, request=req) except ServiceUnavailableException as error: content_type, detail = self.get_error_body(req, error) return HTTPInternalServerError(body=detail, content_type=content_type, request=req) except ItemNotFoundException as error: content_type, detail = self.get_error_body(req, error) return HTTPNotFound(body=detail, content_type=content_type, request=req) except OverLimitException as error: content_type, detail = self.get_error_body(req, error) return HTTPRequestEntityTooLarge(body=detail, content_type=content_type, request=req) except ImmutableEntityException as error: content_type, detail = self.get_error_body(req, error) return HTTPUnprocessableEntity(body=detail, content_type=content_type, request=req) except LoadBalancerFaultException as error: content_type, detail = self.get_error_body(req, error) return HTTPUnauthorized(body=detail, content_type=content_type, request=req) except Exception, msg: exc_type, exc_value, exc_tb = sys.exc_info() tb = traceback.format_exception(exc_type, exc_value, exc_tb) tb.reverse() tb_str = ''.join(tb) self.logger.debug("cannot eval(%s) because %s. Traceback: %s" % (call_pattern, msg, tb_str)) error = ServiceUnavailableException( "The Load Balancing Service is currently unavailable." + " Please contact support") content_type, detail = self.get_error_body(req, error) return HTTPInternalServerError(body=detail, content_type=content_type, request=req)