def test_destroy(self): LoadBalancer.create('fake', 'my-lb', {'LB_ID': 'xxx'}) db_lb = LoadBalancer.find('my-lb') self.assertEqual(db_lb.id, 'xxx') db_lb.destroy() db_lb = LoadBalancer.find('my-lb') self.assertIsNone(db_lb)
def test_destroy_ignores_manager_exception(self, log): LoadBalancer.create('fake', 'my-lb', {'LB_ID': 'explode'}) db_lb = LoadBalancer.find('my-lb') self.assertEqual(db_lb.id, 'explode') db_lb.destroy() self.assertEqual(log.call_args, call("Error trying to destroy load balancer name: 'my-lb' " "id: 'explode' in 'fake': failure to destroy")) db_lb = LoadBalancer.find('my-lb') self.assertIsNone(db_lb)
def test_remove_host(self): h1 = Host('x', 'x.me.com') h2 = Host('y', 'y.me.com') lb = LoadBalancer.create('fake', 'my-lb', {'LB_ID': 'explode'}) lb.add_host(h1) lb.add_host(h2) lb.remove_host(h1) self.assertItemsEqual(lb.hosts, [h2]) db_lb = LoadBalancer.find('my-lb') self.assertItemsEqual([h.to_json() for h in db_lb.hosts], [h2.to_json()])
def test_add_host(self): h1 = Host('x', 'x.me.com') h2 = Host('y', 'y.me.com') conf = {'LB_ID': 'explode'} lb = LoadBalancer.create('fake', 'my-lb', conf) lb.add_host(h1) lb.add_host(h2) self.assertItemsEqual(lb.hosts, [h1, h2]) db_lb = LoadBalancer.find('my-lb', conf) self.assertEqual(db_lb.hosts[0].config, conf) self.assertEqual(db_lb.hosts[1].config, conf) self.assertItemsEqual([h.to_json() for h in db_lb.hosts], [h1.to_json(), h2.to_json()])
def test_create(self): conf = {'LB_ID': 'xxx'} lb = LoadBalancer.create('fake', 'my-lb', conf=conf) self.assertEqual(lb.id, 'xxx') self.assertEqual(lb.name, 'my-lb') self.assertEqual(lb.manager, 'fake') self.assertEqual(lb.extra, 'something') self.assertEqual(lb.config, conf) db_lb = LoadBalancer.find('my-lb', conf=conf) self.assertEqual(db_lb.id, 'xxx') self.assertEqual(db_lb.name, 'my-lb') self.assertEqual(db_lb.manager, 'fake') self.assertEqual(db_lb.extra, 'something') self.assertEqual(db_lb.config, conf)
def new_instance(self, name, team=None, plan_name=None, flavor_name=None): plan = None flavor = None if plan_name: plan = self.storage.find_plan(plan_name) if flavor_name: flavor = self.storage.find_flavor(flavor_name) used, quota = self.storage.find_team_quota(team) if len(used) >= quota: raise QuotaExceededError(len(used), quota) if not self.storage.increment_quota(team, used, name): raise Exception("concurrent operations updating team quota") lb = LoadBalancer.find(name) if lb is not None: raise storage.DuplicateError(name) self.task_manager.create(name) config = copy.deepcopy(self.config) metadata = {} if plan: config.update(plan.config) metadata["plan_name"] = plan_name if flavor: config.update(flavor.config) metadata["flavor_name"] = flavor_name metadata["consul_token"] = consul_token = self.consul_manager.generate_token(name) self.consul_manager.write_healthcheck(name) self.storage.store_instance_metadata(name, **metadata) self._add_tags(name, config, consul_token) task = tasks.NewInstanceTask().delay(config, name) self.task_manager.update(name, task.task_id)
def run(self, config, name): self.init_config(config) healthcheck_timeout = int(self._get_conf("RPAAS_HEALTHCHECK_TIMEOUT", 600)) host = Host.create(self.host_manager_name, name, self.config) lb = None try: lb = LoadBalancer.create(self.lb_manager_name, name, self.config) lb.add_host(host) self.nginx_manager.wait_healthcheck(host.dns_name, timeout=healthcheck_timeout) self.hc.create(name) self.hc.add_url(name, host.dns_name) self.storage.remove_task(name) except: exc_info = sys.exc_info() rollback = self._get_conf("RPAAS_ROLLBACK_ON_ERROR", "0") in ("True", "true", "1") if not rollback: raise try: if lb is not None: lb.destroy() except Exception as e: logging.error("Error in rollback trying to destroy load balancer: {}".format(e)) try: host.destroy() except Exception as e: logging.error("Error in rollback trying to destroy host: {}".format(e)) try: self.hc.destroy(name) except Exception as e: logging.error("Error in rollback trying to remove healthcheck: {}".format(e)) raise exc_info[0], exc_info[1], exc_info[2]
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 add_block(self, name, block_name, content): self._ensure_ready(name) block_name = block_name.strip() lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() self.consul_manager.write_block(name, block_name, content)
def info(self, name): addr = self._get_address(name) routes_data = [] binding_data = self.storage.find_binding(name) if binding_data: paths = binding_data.get('paths') or [] for path_data in paths: routes_data.append("path = {}".format(path_data['path'])) dst = path_data.get('destination') content = path_data.get('content') if dst: routes_data.append("destination = {}".format(dst)) if content: routes_data.append("content = {}".format(content)) lb = LoadBalancer.find(name) host_count = 0 if lb: host_count = len(lb.hosts) return [ { "label": "Address", "value": addr, }, { "label": "Instances", "value": str(host_count), }, { "label": "Routes", "value": "\n".join(routes_data), }, ]
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() 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 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 update_certificate(self, name, cert, key): self._ensure_ready(name) lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() self.storage.update_binding_certificate(name, cert, key) for host in lb.hosts: self.nginx_manager.update_certificate(host.dns_name, cert, key)
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 add_route(self, name, path, destination, content, https_only): 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, https_only) self.consul_manager.write_location(name, path, destination=destination, content=content, https_only=https_only)
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 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 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() self.hc.destroy(name)
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 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 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_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 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 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 _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 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 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 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 _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 _add_host(self, name, lb=None): healthcheck_timeout = int( self._get_conf("RPAAS_HEALTHCHECK_TIMEOUT", 600)) created_lb = None try: if not lb: lb = created_lb = LoadBalancer.create(self.lb_manager_name, name, self.config) self.hc.create(name) config = copy.deepcopy(self.config) if hasattr(lb, 'dsr') and lb.dsr: config["HOST_TAGS"] = config[ "HOST_TAGS"] + ",dsr_ip:{}".format(lb.address) host = Host.create(self.host_manager_name, name, config) lb.add_host(host) self.nginx_manager.wait_healthcheck(host.dns_name, timeout=healthcheck_timeout) acls = self.consul_manager.find_acl_network(name) if acls: acl_host = acls.pop() for dst in acl_host['destination']: self.acl_manager.add_acl(name, host.dns_name, dst) self.hc.add_url(name, host.dns_name) except: exc_info = sys.exc_info() rollback = self._get_conf("RPAAS_ROLLBACK_ON_ERROR", "0") in ("True", "true", "1") if not rollback: raise try: if created_lb is not None: created_lb.destroy() except Exception as e: logging.error( "Error in rollback trying to destroy load balancer: {}". format(e)) try: if created_lb is not None: self._delete_host(name, host) else: self._delete_host(name, host, lb) except Exception as e: logging.error( "Error in rollback trying to destroy host: {}".format(e)) try: if lb and len(lb.hosts) == 0: self.hc.destroy(name) except Exception as e: logging.error( "Error in rollback trying to remove healthcheck: {}". format(e)) raise exc_info[0], exc_info[1], exc_info[2] finally: self.storage.remove_task(name)
def unbind(self, name): 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 bound_host = binding_data.get("app_host") self.storage.remove_root_binding(name) self.consul_manager.write_location(name, "/", content=nginx.NGINX_LOCATION_INSTANCE_NOT_BOUND) self.consul_manager.remove_server_upstream(name, "rpaas_default_upstream", bound_host)
def new_instance(self, name, team=None): used, quota = self.storage.find_team_quota(team) if len(used) >= quota: raise QuotaExceededError(len(used), quota) if not self.storage.increment_quota(team, used, name): raise Exception("concurrent operations updating team quota") lb = LoadBalancer.find(name) if lb is not None: raise storage.DuplicateError(name) self.storage.store_task(name) task = tasks.NewInstanceTask().delay(self.config, name) self.storage.update_task(name, task.task_id)
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 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) self.consul_manager.destroy_instance(name) 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 list_blocks(self, name): self._ensure_ready(name) lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() blocks = self.consul_manager.list_blocks(name) block_list = [] if blocks[1]: block_list = [ {'block_name': block['Key'].split('/')[-2], 'content': block['Value']} for block in blocks[1] ] return block_list
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)
def restore_machine_instance(self, name, machine, cancel_task=False): task_name = "restore_{}".format(machine) if cancel_task: self.task_manager.remove(task_name) return self.task_manager.ensure_ready(task_name) lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() machine_data = self.storage.find_host_id(machine) if machine_data is None: raise InstanceMachineNotFoundError() self.task_manager.create({"_id": task_name, "host": machine, "instance": name, "created": datetime.datetime.utcnow()})
def unbind(self, name): 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 bound_host = binding_data.get("app_host") self.storage.remove_root_binding(name) self.consul_manager.write_location( name, "/", content=nginx.NGINX_LOCATION_INSTANCE_NOT_BOUND) self.consul_manager.remove_server_upstream(name, "rpaas_default_upstream", bound_host)
def run(self, config, name, plugin, domain): try: self.init_config(config) lb = LoadBalancer.find(name, self.config) if lb is None: raise storage.InstanceNotFoundError() plugin_class = ssl_plugins.get(plugin) plugin_obj = plugin_class(domain, os.environ.get('RPAAS_PLUGIN_LE_EMAIL', 'admin@'+domain), name) plugin_obj.revoke() self.storage.remove_le_certificate(name, domain) except Exception, e: logging.error("Error in ssl plugin task: {}".format(e)) raise e
def node_status(self, name): lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() hostnames = {} for host in lb.hosts: hostname = self.consul_manager.node_hostname(host.dns_name) if hostname is not None: hostnames[hostname] = host.dns_name node_status_return = {} for node, status in self.consul_manager.node_status(name).iteritems(): node_status_return[node] = {'status': status} if node in hostnames: node_status_return[node]['address'] = hostnames[node] return node_status_return
def bind(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 binding_data: bound_host = binding_data.get("app_host") if bound_host == app_host: # Nothing to do, already bound return if bound_host is not None: raise BindError("This service can only be bound to one application.") self.consul_manager.write_location(name, "/", destination=app_host) self.storage.store_binding(name, app_host)
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) self.consul_manager.destroy_instance(name) if self._should_destroy_lb(): lb.destroy() else: logging.info('Skipping load balancer ({}/{}) removal', lb.id, lb.name) for cert in self.storage.find_le_certificates({'name': name}): self.storage.remove_le_certificate(name, cert['domain']) self.hc.destroy(name)
def execute(self, config, name, quantity): try: self.init_config(config) lb = LoadBalancer.find(name, self.config) if lb is None: raise storage.InstanceNotFoundError() diff = quantity - len(lb.hosts) if diff == 0: return for i in xrange(abs(diff)): if diff > 0: self._add_host(name, lb=lb) else: self._delete_host(name, lb.hosts[i], lb) finally: self.storage.remove_task(name)
def bind(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 binding_data: bound_host = binding_data.get('app_host') if bound_host == app_host: # Nothing to do, already bound return if bound_host is not None: raise BindError( 'This service can only be bound to one application.') for host in lb.hosts: self.nginx_manager.update_binding(host.dns_name, '/', app_host) self.storage.store_binding(name, app_host)
def run(self, config, name, plugin, csr, key, domain): try: self.init_config(config) lb = LoadBalancer.find(name, self.config) if lb is None: raise storage.InstanceNotFoundError() crt = None # Get plugin class p_ssl = getattr(getattr(__import__('rpaas'), 'ssl_plugins'), plugin) for obj_name, obj in inspect.getmembers(p_ssl): if obj_name != 'BaseSSLPlugin' and \ inspect.isclass(obj) and \ issubclass(obj, rpaas.ssl_plugins.BaseSSLPlugin): hosts = [host.dns_name for host in lb.hosts] c_ssl = obj( domain, os.environ.get('RPAAS_PLUGIN_LE_EMAIL', 'admin@' + domain), hosts) # Upload csr and get an Id plugin_id = c_ssl.upload_csr(csr) crt = c_ssl.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 for host in lb.hosts: self.nginx_manager.update_certificate( host.dns_name, cert, key) else: raise Exception('Could not download certificate') except Exception, e: logging.error("Error in ssl plugin task: {}".format(e)) raise e
def revoke_ssl(self, name, plugin='default'): lb = LoadBalancer.find(name) if lb is None: raise storage.InstanceNotFoundError() if plugin.isalpha() and plugin in ssl_plugins.__all__ and \ plugin not in ['default', '__init__']: try: self.task_manager.create(name) task = tasks.RevokeCertTask().dealy(self.config, name, plugin) self.task_manager.update(name, task.task_id) return '' except Exception: raise SslError('rpaas IP is not registered for this DNS name') else: raise SslError('SSL plugin not defined') return ''
def new_instance(self, name, team=None, plan_name=None): plan = None if plan_name: plan = self.storage.find_plan(plan_name) used, quota = self.storage.find_team_quota(team) if len(used) >= quota: raise QuotaExceededError(len(used), quota) if not self.storage.increment_quota(team, used, name): raise Exception("concurrent operations updating team quota") lb = LoadBalancer.find(name) if lb is not None: raise storage.DuplicateError(name) self.storage.store_task(name) config = copy.deepcopy(self.config) if plan: config.update(plan.config) self.storage.store_instance_metadata(name, plan_name=plan_name) self._add_tags(name, config) task = tasks.NewInstanceTask().delay(config, name) self.storage.update_task(name, task.task_id)
def run(self, config): self.init_config(config) session_resumption_rotate = int(self.config.get("SESSION_RESUMPTION_TICKET_ROTATE", 3600)) instances_to_rotate = self.config.get("SESSION_RESUMPTION_INSTANCES", None) service_name = self.config.get("RPAAS_SERVICE_NAME", "rpaas") service_instance_lock = "session_resumption:{}:instance".format(service_name) instance_lock = self.config.get("SESSION_RESUMPTION_INSTANCE_LOCK_PREFIX", service_instance_lock) if instances_to_rotate: instances_to_rotate = instances_to_rotate.split(",") lb_data = LoadBalancer.list(conf=self.config) for lb in lb_data: if instances_to_rotate and lb.name not in instances_to_rotate: continue lock_name = "{}:{}".format(instance_lock, lb.name) if self.lock_manager.lock(lock_name, session_resumption_rotate): try: self.rotate_session_ticket(lb.hosts) except Exception as e: logging.error("Error renewing session ticket for {}: {}".format(lb.name, repr(e))) finally: self.lock_manager.unlock(lock_name)
def info(self, name): addr = self._get_address(name) routes_data = [] binding_data = self.storage.find_binding(name) if binding_data: paths = binding_data.get("paths") or [] for path_data in paths: routes_data.append("path = {}".format(path_data["path"])) dst = path_data.get("destination") content = path_data.get("content") https_only = path_data.get("https_only") if https_only and dst: dst = "{} (https only)".format(dst) if dst: routes_data.append("destination = {}".format(dst)) if content: routes_data.append("content = {}".format( content.encode("utf-8"))) lb = LoadBalancer.find(name) host_count = 0 if lb: host_count = len(lb.hosts) data = [ { "label": "Address", "value": addr, }, { "label": "Instances", "value": str(host_count), }, { "label": "Routes", "value": "\n".join(routes_data), }, ] metadata = self.storage.find_instance_metadata(name) if metadata and "plan_name" in metadata: data.append({"label": "Plan", "value": metadata["plan_name"]}) return data
def run(self, config, name): self.init_config(config) healthcheck_timeout = int( self._get_conf("RPAAS_HEALTHCHECK_TIMEOUT", 600)) host = Host.create(self.host_manager_name, name, self.config) lb = None try: lb = LoadBalancer.create(self.lb_manager_name, name, self.config) lb.add_host(host) self.nginx_manager.wait_healthcheck(host.dns_name, timeout=healthcheck_timeout) self.hc.create(name) self.hc.add_url(name, host.dns_name) self.storage.remove_task(name) except: exc_info = sys.exc_info() rollback = self._get_conf("RPAAS_ROLLBACK_ON_ERROR", "0") in ("True", "true", "1") if not rollback: raise try: if lb is not None: lb.destroy() except Exception as e: logging.error( "Error in rollback trying to destroy load balancer: {}". format(e)) try: host.destroy() except Exception as e: logging.error( "Error in rollback trying to destroy host: {}".format(e)) try: self.hc.destroy(name) except Exception as e: logging.error( "Error in rollback trying to remove healthcheck: {}". format(e)) raise exc_info[0], exc_info[1], exc_info[2]