def delete_route(self, name, path): self.task_manager.ensure_ready(name) path = path.strip() if path == "/": raise RouteError( "You cannot remove a route for / location, unbind the app.") lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() routes = self.list_routes(name) destination_count = 0 if not routes: raise storage.InstanceNotFoundError() destination = [ p['destination'] for p in routes['paths'] if p['path'] == path ] if len(destination) > 0: destination = destination.pop() else: destination = None for p in routes['paths']: if destination and p['destination'] == destination: destination_count += 1 if destination_count == 0: raise storage.InstanceNotFoundError() if destination_count < 2: self.consul_manager.remove_server_upstream(name, destination, destination) self.storage.delete_binding_path(name, path) self.consul_manager.remove_location(name, path)
def swap(self, instance_a, instance_b): _, instance_a = self.find_instance(instance_a) _, instance_b = self.find_instance(instance_b) if not instance_a: raise storage.InstanceNotFoundError() if not instance_b: raise consul_manager.InstanceAlreadySwappedError()
def add_lua(self, name, lua_module_name, lua_module_type, content): self.task_manager.ensure_ready(name) lb = LoadBalancer.find(name) if lb is None: storage.InstanceNotFoundError() self.consul_manager.write_lua(name, lua_module_name, lua_module_type, content)
def remove_upstream(self, name, upstream_name, servers): self.task_manager.ensure_ready(name) lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() self.consul_manager.remove_server_upstream(name, upstream_name, servers)
def remove_instance(self, name): if name == 'router-swap_error': raise consul_manager.InstanceAlreadySwappedError() index, _ = self.find_instance(name) if index == -1: raise storage.InstanceNotFoundError() del self.instances[index]
def delete_block(self, name, block_name): self.task_manager.ensure_ready(name) block_name = block_name.strip() lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() self.consul_manager.remove_block(name, block_name)
def update_instance(self, name, plan_name): if plan_name: self.storage.find_plan(plan_name) index, _ = self.find_instance(name) if index == -1: raise storage.InstanceNotFoundError() self.instances[index].plan = plan_name
def get_certificate(self, name): index, instance = self.find_instance(name) if index < 0: raise storage.InstanceNotFoundError() if not instance.cert or not instance.key: raise consul_manager.CertificateNotFoundError() return instance.cert, instance.key
def generate_crt(config, name, plugin, csr, key, domain): lb = LoadBalancer.find(name, config) if lb is None: raise storage.InstanceNotFoundError() strg = storage.MongoDBStorage(config) consul_mngr = consul_manager.ConsulManager(config) crt = None plugin_class = ssl_plugins.get(plugin) if not plugin_class: raise Exception("Invalid plugin {}".format(plugin)) plugin_obj = plugin_class(domain, os.environ.get('RPAAS_PLUGIN_LE_EMAIL', 'admin@'+domain), name, consul_manager=consul_mngr) # Upload csr and get an Id plugin_id = plugin_obj.upload_csr(csr) crt = plugin_obj.download_crt(id=str(plugin_id)) # Download the certificate and update nginx with it if crt: try: js_crt = json.loads(crt) cert = js_crt['crt'] cert = cert+js_crt['chain'] if 'chain' in js_crt else cert key = js_crt['key'] if 'key' in js_crt else key except: cert = crt consul_mngr.set_certificate(name, cert, key) strg.store_le_certificate(name, domain) else: raise Exception('Could not download certificate')
def update_certificate(self, name, cert, key): self.task_manager.ensure_ready(name) lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() self.storage.update_binding_certificate(name, cert, key) self.consul_manager.set_certificate(name, cert, key)
def activate_ssl(self, name, domain, plugin='default'): lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() # Check if DNS is registered for rpaas ip if not self._check_dns(name, domain): raise SslError('rpaas IP is not registered for this DNS name') # Key and CSR generated to request a certificate key = self._generate_key() csr = self._generate_csr(key, domain) # load plugin if get it as an arg if plugin.isalpha() and plugin in rpaas.ssl_plugins.__all__ and \ plugin not in ['default', '__init__']: try: self.storage.store_task(name) task = tasks.DownloadCertTask().delay(self.config, name, plugin, csr, key, domain) self.storage.update_task(name, task.task_id) return '' except Exception: raise SslError('rpaas IP is not registered for this DNS name') else: # default p_ssl = rpaas.ssl_plugins.default.Default(domain) cert = p_ssl.download_crt(key=key) self.update_certificate(name, cert, key) return ''
def activate_ssl(self, name, domain, plugin='default'): lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() if not self._check_dns(name, domain): raise SslError('rpaas IP is not registered for this DNS name') key = ssl.generate_key() csr = ssl.generate_csr(key, domain) if plugin == 'le': try: self.task_manager.create(name) task = tasks.DownloadCertTask().delay(self.config, name, plugin, csr, key, domain) self.task_manager.update(name, task.task_id) return '' except Exception: raise SslError('rpaas IP is not registered for this DNS name') else: p_ssl = ssl_plugins.default.Default(domain) cert = p_ssl.download_crt(key=key) self.update_certificate(name, cert, key) return ''
def swap(self, src_instance, dst_instance): self.task_manager.ensure_ready(src_instance) self.task_manager.ensure_ready(dst_instance) for instance in [src_instance, dst_instance]: lb = LoadBalancer.find(instance) if lb is None: raise storage.InstanceNotFoundError(instance) self.consul_manager.swap_instances(src_instance, dst_instance)
def add_route(self, name, path, destination, content): self.task_manager.ensure_ready(name) path = path.strip() lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() self.storage.replace_binding_path(name, path, destination, content) self.consul_manager.write_location(name, path, destination=destination, content=content)
def scale_instance(self, name, quantity): if quantity < 1: raise ValueError("invalid quantity: %d" % quantity) index, instance = self.find_instance(name) if index < 0: raise storage.InstanceNotFoundError() difference = quantity - instance.units instance.units += difference self.instances[index] = instance
def run(self, config, name): self.init_config(config) lb = LoadBalancer.find(name, self.config) if lb is None: raise storage.InstanceNotFoundError() for host in lb.hosts: host.destroy() lb.destroy() self.hc.destroy(name)
def delete_route(self, name, path): self.task_manager.ensure_ready(name) path = path.strip() if path == "/": raise RouteError("You cannot remove a route for / location, unbind the app.") lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() self.storage.delete_binding_path(name, path) self.consul_manager.remove_location(name, path)
def update_certificate(self, name, cert, key): self._ensure_ready(name) lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() # if not self._verify_crt(cert, key): # raise SslError('Invalid certificate') self.storage.update_binding_certificate(name, cert, key) for host in lb.hosts: self.nginx_manager.update_certificate(host.dns_name, cert, key)
def add_route(self, name, path, destination, content): self._ensure_ready(name) path = path.strip() lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() self.storage.replace_binding_path(name, path, destination, content) for host in lb.hosts: self.nginx_manager.update_binding(host.dns_name, path, destination, content)
def update_instance(self, name, plan_name): if not self.storage.find_plan(plan_name): raise storage.PlanNotFoundError() self.task_manager.ensure_ready(name) lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() metadata = self.storage.find_instance_metadata(name) metadata['plan_name'] = plan_name self.storage.store_instance_metadata(name, **metadata)
def unbind(self, name, app_host): self.task_manager.ensure_ready(name) lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() binding_data = self.storage.find_binding(name) if not binding_data: return self.storage.remove_root_binding(name) self.consul_manager.remove_location(name, "/")
def restore_instance(self, name): self.task_manager.ensure_ready(name) self.task_manager.create(name) config = copy.deepcopy(self.config) metadata = self.storage.find_instance_metadata(name) if metadata and "plan_name" in metadata: plan = self.storage.find_plan(metadata["plan_name"]) config.update(plan.config or {}) healthcheck_timeout = int(config.get("RPAAS_HEALTHCHECK_TIMEOUT", 600)) tags = [] extra_tags = config.get("INSTANCE_EXTRA_TAGS", "") if extra_tags: tags.append(extra_tags) config["HOST_TAGS"] = ",".join(tags) try: self.task_manager.update(name, uuid()) lb = LoadBalancer.find(name, config) if lb is None: raise storage.InstanceNotFoundError() length = len(lb.hosts) for idx, host in enumerate(lb.hosts): yield "Restoring host ({}/{}) {} ".format( idx + 1, length, host.id) restore_host_job = JobWaiting(host.restore, 0, reset_template=True, reset_tags=True) restore_host_job.start() while restore_host_job.is_alive(): yield "." time.sleep(1) if isinstance(restore_host_job.result, Exception): raise restore_host_job.result host.start() nginx_waiting = self.nginx_manager.wait_healthcheck restore_delay = int(config.get("RPAAS_RESTORE_DELAY", 30)) nginx_healthcheck_job = JobWaiting(nginx_waiting, restore_delay, host=host.dns_name, timeout=healthcheck_timeout, manage_healthcheck=False) nginx_healthcheck_job.start() while nginx_healthcheck_job.is_alive(): yield "." time.sleep(1) if isinstance(nginx_healthcheck_job.result, Exception): raise nginx_healthcheck_job.result yield ": successfully restored\n" except storage.InstanceNotFoundError: yield "instance {} not found\n".format(name) except Exception as e: yield ": failed to restore - {}\n".format(repr(e.message)) finally: self.task_manager.remove(name)
def _get_address(self, name): task = self.storage.find_task(name) if task: result = tasks.NewInstanceTask().AsyncResult(task['task_id']) if result.status in ['FAILURE', 'REVOKED']: return FAILURE return PENDING lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() return lb.address
def _get_address(self, name): task = self.storage.find_task(name) if task.count() >= 1: result = tasks.NewInstanceTask().AsyncResult(task[0]["task_id"]) if result.status in ["FAILURE", "REVOKED"]: return FAILURE return PENDING lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() return lb.address
def unbind(self, name, app_host): self._ensure_ready(name) lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() binding_data = self.storage.find_binding(name) if not binding_data: return self.storage.remove_root_binding(name) for host in lb.hosts: self.nginx_manager.delete_binding(host.dns_name, '/')
def run(self, config, name): self.init_config(config) lb = LoadBalancer.find(name, self.config) if lb is None: raise storage.InstanceNotFoundError() for host in lb.hosts: self._delete_host(name, host, lb) lb.destroy() for cert in self.storage.find_le_certificates({'name': name}): self.storage.remove_le_certificate(name, cert['domain']) self.hc.destroy(name)
def purge_location(self, name, path): self.task_manager.ensure_ready(name) path = path.strip() lb = LoadBalancer.find(name) purged_hosts = 0 if lb is None: raise storage.InstanceNotFoundError() for host in lb.hosts: if self.nginx_manager.purge_location(host.dns_name, path): purged_hosts += 1 return purged_hosts
def update_instance(self, name, plan_name=None, flavor_name=None): index, _ = self.find_instance(name) if index == -1: raise storage.InstanceNotFoundError() if plan_name: self.storage.find_plan(plan_name) if flavor_name: self.storage.find_flavor(flavor_name) self.instances[index].flavor = flavor_name if plan_name: self.instances[index].plan = plan_name
def delete_route(self, name, path): self._ensure_ready(name) path = path.strip() if path == '/': raise RouteError( "You cannot remove a route for / location, unbind the app.") lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() self.storage.delete_binding_path(name, path) for host in lb.hosts: self.nginx_manager.delete_binding(host.dns_name, path)
def add_upstream(self, name, upstream_name, servers, acl=False): self.task_manager.ensure_ready(name) lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() if acl: for host in lb.hosts: if not isinstance(servers, list): servers = [servers] for server in servers: dst_host, _ = host_from_destination(server) self.acl_manager.add_acl(name, host.dns_name, dst_host) self.consul_manager.add_server_upstream(name, upstream_name, servers)