def get_netloc(): '''Get the network location (host:port) for this registry. If http-host config is present, return the netloc for that config. If related to a proxy, return the proxy netloc. Otherwise, return our private_adddress:port. ''' charm_config = hookenv.config() netloc = None if charm_config.get('http-host'): netloc = urlparse(charm_config['http-host']).netloc else: # use the proxy address for our netloc (if available) proxy = endpoint_from_flag('website.available') if proxy: proxy_addrs = [ hookenv.ingress_address(rid=u.rid, unit=u.unit) for u in hookenv.iter_units_for_relation_name(proxy.endpoint_name) ] # NB: get the first addr; presumably, the first will work just as # well as any other. try: netloc = proxy_addrs[0] except IndexError: # If we fail here, the proxy is probably departing; fall out # to the default netloc. pass if not netloc: netloc = '{}:{}'.format(hookenv.unit_private_ip(), charm_config.get('registry-port', '5000')) return netloc
def get_tls_sans(relation_name=None): '''Get all sans for our TLS certificate. Return all IP/DNS data that should included as alt names when we request a TLS cert. This includes our public/private address, local DNS name, any configured hostname, and the address of any related proxy. :return: sorted list of sans ''' charm_config = hookenv.config() sans = [ hookenv.unit_private_ip(), hookenv.unit_public_ip(), socket.gethostname(), ] if charm_config.get('http-host'): http_host = urlparse(charm_config['http-host']).hostname sans.append(http_host) if relation_name: proxy_sans = [hookenv.ingress_address(rid=u.rid, unit=u.unit) for u in hookenv.iter_units_for_relation_name(relation_name)] sans.extend(proxy_sans) return sorted(sans)
def setup_ufw(): """Setup UFW firewall to ensure only swift-storage clients and storage peers have access to the swift daemons. :side effect: calls several external functions :return: None """ if not config('enable-firewall'): log("Firewall has been administratively disabled", "DEBUG") return ports = [config('object-server-port'), config('container-server-port'), config('account-server-port')] # Storage peers allowed_hosts = RsyncContext()().get('allowed_hosts', '').split(' ') # Storage clients (swift-proxy) allowed_hosts += [get_host_ip(ingress_address(rid=u.rid, unit=u.unit)) for u in iter_units_for_relation_name('swift-storage')] # Grant access for peers and clients for host in allowed_hosts: for port in ports: grant_access(host, port) # Default deny for storage ports for port in ports: ufw.modify_access(src=None, dst='any', port=port, proto='tcp', action='reject')
def swift_storage_relation_departed(): ports = [config('object-server-port'), config('container-server-port'), config('account-server-port')] removed_client = ingress_address() if removed_client: for port in ports: revoke_access(removed_client, port)
def get_internal_api_endpoints(relation=None): """ Determine the best API endpoints for an internal client to connect to. If a relation is given, it will try to take that into account. May return an empty list if an endpoint is expected but not yet available. """ try: goal_state = hookenv.goal_state() except NotImplementedError: goal_state = {} goal_state.setdefault("relations", {}) # Config takes precedence. endpoints_from_config = get_endpoints_from_config() if endpoints_from_config: return endpoints_from_config # If the internal LB relation is attached, use that or nothing. If it's # not attached but the external LB relation is, use that or nothing. for lb_type in ("internal", "external"): lb_endpoint = "loadbalancer-" + lb_type request_name = "api-server-" + lb_type api_port = EXTERNAL_API_PORT if lb_type == "external" else STANDARD_API_PORT if lb_endpoint in goal_state["relations"]: lb_provider = endpoint_from_name(lb_endpoint) lb_response = lb_provider.get_response(request_name) if not lb_response or lb_response.error: return [] return [(lb_response.address, api_port)] # Support the older loadbalancer relation (public-address interface). if "loadbalancer" in goal_state["relations"]: loadbalancer = endpoint_from_name("loadbalancer") lb_addresses = loadbalancer.get_addresses_ports() return [(host.get("public-address"), host.get("port")) for host in lb_addresses] # No LBs of any kind, so fall back to ingress-address. if not relation: kube_control = endpoint_from_name("kube-control") if not kube_control.relations: return [] relation = kube_control.relations[0] ingress_address = hookenv.ingress_address(relation.relation_id, hookenv.local_unit()) return [(ingress_address, STANDARD_API_PORT)]
def get_api_endpoint(relation=None): """ Determine the best endpoint for a client to connect to. If a relation is given, it will take that into account when choosing an endpoint. """ endpoints = get_lb_endpoints() if endpoints: # select a single endpoint based on our local unit number return endpoints[kubernetes_common.get_unit_number() % len(endpoints)] elif relation: ingress_address = hookenv.ingress_address(relation.relation_id, hookenv.local_unit()) return (ingress_address, STANDARD_API_PORT) else: return (hookenv.unit_public_ip(), STANDARD_API_PORT)
def get_ingress_address(self, rel_id=None): if rel_id is None: rel_id = self.relations[0].relation_id return hookenv.ingress_address(rel_id, hookenv.local_unit())
def get_ingress_address(self, rel_id=None): # If no rel_id is provided, we fallback to the first one if rel_id is None: rel_id = self.relations[0].relation_id return hookenv.ingress_address(rel_id, hookenv.local_unit())