def _build_ingress(self, metadata): """Build ingress Kubernetes object. :param metadata: Common Kubernetes metadata for the interactive deployment. """ ingress_backend = client.NetworkingV1beta1IngressBackend( service_name=self.deployment_name, service_port=InteractiveDeploymentK8sBuilder.internal_service_port, ) ingress_rule_value = client.NetworkingV1beta1HTTPIngressRuleValue( [ client.NetworkingV1beta1HTTPIngressPath( path=self.path, backend=ingress_backend ) ] ) spec = client.NetworkingV1beta1IngressSpec( rules=[client.NetworkingV1beta1IngressRule(http=ingress_rule_value)] ) ingress = client.NetworkingV1beta1Ingress( api_version="networking.k8s.io/v1beta1", kind="Ingress", spec=spec, metadata=metadata, ) return ingress
def build_ingress(services, dns_suffix, dual_dns_prefix_annotation_name, ingress_info): ingress = client.NetworkingV1beta1Ingress() # init metadata ingress.metadata = client.V1ObjectMeta() ingress.metadata.name = ingress_info["ingress_name"] # init spec ingress.spec = client.NetworkingV1beta1IngressSpec() ingress.spec.rules = [] service_tuples = _create_ingress_service_tuples( services, dual_dns_prefix_annotation_name) for dns_prefix, port, service in service_tuples: ingress_rule = client.NetworkingV1beta1IngressRule() ingress_rule.host = "%s.%s" % (dns_prefix, dns_suffix) backend = client.NetworkingV1beta1IngressBackend( service_name=service.metadata.name, service_port=port) ingress_path = [ client.NetworkingV1beta1HTTPIngressPath(path="/", backend=backend) ] ingress_rule.http = client.NetworkingV1beta1HTTPIngressRuleValue( ingress_path) ingress.spec.rules.append(ingress_rule) if not ingress.spec.rules: ingress_dummy_backend = client.NetworkingV1beta1IngressBackend( service_name=ingress_info["ingress_controller_service_name"], service_port=80) ingress.spec.backend = ingress_dummy_backend return ingress
def build_ingress(services, dns_suffix, dual_dns_prefix_annotation_name, ingress_info): ingress = client.NetworkingV1beta1Ingress() # init metadata ingress.metadata = client.V1ObjectMeta() ingress.metadata.name = ingress_info["ingress_name"] # init spec ingress.spec = client.NetworkingV1beta1IngressSpec() ingress.spec.rules = [] service_tuples = _create_ingress_service_tuples( services, dual_dns_prefix_annotation_name) # A little bit of a hack to have the ingress put the port:443 entries before the port:80 entries, # so that the port:80 entries take precedence if the service name is the same. Without this # we get ssl errors when accessing services behind the ingress locally because of k3d internals service_tuples = sorted(service_tuples, key=lambda x: x[1], reverse=True) for dns_prefix, port, service in service_tuples: ingress_rule = client.NetworkingV1beta1IngressRule() ingress_rule.host = "%s.%s" % (dns_prefix, dns_suffix) backend = client.NetworkingV1beta1IngressBackend( service_name=service.metadata.name, service_port=port) ingress_path = [ client.NetworkingV1beta1HTTPIngressPath(path="/", backend=backend) ] ingress_rule.http = client.NetworkingV1beta1HTTPIngressRuleValue( ingress_path) ingress.spec.rules.append(ingress_rule) if not ingress.spec.rules: ingress_dummy_backend = client.NetworkingV1beta1IngressBackend( service_name=ingress_info["ingress_controller_service_name"], service_port=80) ingress.spec.backend = ingress_dummy_backend return ingress
def create_ingress(networking_v1_beta1_api): body = client.NetworkingV1beta1Ingress( api_version="networking.k8s.io/v1beta1", kind="Ingress", metadata=client.V1ObjectMeta(name="ingress-example", annotations={ "nginx.ingress.kubernetes.io/rewrite-target": "/" }), spec=client.NetworkingV1beta1IngressSpec( rules=[client.NetworkingV1beta1IngressRule( host="example.com", http=client.NetworkingV1beta1HTTPIngressRuleValue( paths=[client.NetworkingV1beta1HTTPIngressPath( path="/", backend=client.NetworkingV1beta1IngressBackend( service_port=5678, service_name="service-example") )] ) ) ] ) ) # Creation of the Deployment in specified namespace # (Can replace "default" with a namespace you may have created) networking_v1_beta1_api.create_namespaced_ingress( namespace="default", body=body )
def create_ingress(api_instance, namespacename, resourceendpoint,resourceurl,resourceid): try: body = client.NetworkingV1beta1Ingress( api_version="networking.k8s.io/v1beta1", kind="Ingress", metadata=client.V1ObjectMeta(name=resourceid, annotations={ "nginx.ingress.kubernetes.io/rewrite-target": resourceurl }), spec=client.NetworkingV1beta1IngressSpec( rules=[client.NetworkingV1beta1IngressRule( http=client.NetworkingV1beta1HTTPIngressRuleValue( paths=[client.NetworkingV1beta1HTTPIngressPath( path=resourceendpoint, backend=client.NetworkingV1beta1IngressBackend( service_port=80, service_name=resourceid) )] ) ) ] ) ) # Creation of the Deployment in specified namespace # (Can replace "default" with a namespace you may have created) api_response = api_instance.create_namespaced_ingress( namespace=namespacename, body=body ) return("success", "Ingress_Intiated", api_response) except Exception as Error: return("error", "Ingress_Intiation_Failed", str(Error))
def create_k8s_ingress(namespace: str, name: str, annotations: dict, tls: bool, rules: dict, user): """ Create a Kubernetes ingress in the cluster. The Kubeportal API makes some simplifying assumptions: - TLS is a global configuration for an Ingress. - The necessary annotations come from the portal settings, not from the ingress definition. """ net_v1 = get_user_net_v1(user) logger.info(f"Creating Kubernetes ingress '{name}'") k8s_annotations = {item['key']: item['value'] for item in annotations} k8s_ing = client.NetworkingV1beta1Ingress( metadata=client.V1ObjectMeta(name=name, annotations=k8s_annotations)) k8s_rules = [] k8s_hosts = [] for rule in rules: host = rule["host"] k8s_hosts.append(host) paths = rule["paths"] k8s_rule = client.NetworkingV1beta1IngressRule(host=host) k8s_paths = [] for path_config in paths: k8s_backend = client.NetworkingV1beta1IngressBackend( service_name=path_config['service_name'], service_port=path_config['service_port']) k8s_paths.append( client.NetworkingV1beta1HTTPIngressPath(path=path_config.get( "path", None), backend=k8s_backend)) k8s_http = client.NetworkingV1beta1HTTPIngressRuleValue( paths=k8s_paths) k8s_rule.http = k8s_http k8s_rules.append(k8s_rule) k8s_spec = client.NetworkingV1beta1IngressSpec(rules=k8s_rules) if tls: k8s_ing.metadata.annotations[ 'cert-manager.io/cluster-issuer'] = settings.INGRESS_TLS_ISSUER k8s_spec.tls = [ client.NetworkingV1beta1IngressTLS(hosts=k8s_hosts, secret_name=f'{name}_tls') ] k8s_ing.spec = k8s_spec net_v1.create_namespaced_ingress(namespace, k8s_ing)
def get(self): return client.NetworkingV1beta1Ingress( api_version='networking.k8s.io/v1beta1', kind='Ingress', metadata=client.V1ObjectMeta( name='ingress-django-app', annotations={'kubernetes.io/ingress.class': 'nginx'}), spec=client.NetworkingV1beta1IngressSpec(rules=[ client.NetworkingV1beta1IngressRule( host='local.kangox.com', http=client.NetworkingV1beta1HTTPIngressRuleValue(paths=[ client.NetworkingV1beta1HTTPIngressPath( path='/', backend=client.NetworkingV1beta1IngressBackend( service_name='django-app', service_port=8080)) ])) ]))
def create_ingress(networking_v1_beta1_api, username): name = 'jlab-{}'.format(username) try: # TODO: Improve this parameterization so that no cluster-specific details are hard-coded body = client.NetworkingV1beta1Ingress( api_version="networking.k8s.io/v1beta1", kind="Ingress", metadata=client.V1ObjectMeta(name=name, annotations={ 'kubernetes.io/ingress.class': envvars.INGRESS_CLASS_JLAB_SERVER }), spec=client.NetworkingV1beta1IngressSpec( tls=[ client.ExtensionsV1beta1IngressTLS( hosts=[ envvars.BASE_DOMAIN ], secret_name=envvars.TLS_SECRET ) ], rules=[client.NetworkingV1beta1IngressRule( host=envvars.BASE_DOMAIN, http=client.NetworkingV1beta1HTTPIngressRuleValue( paths=[client.NetworkingV1beta1HTTPIngressPath( path="{}/jlab/{}".format(envvars.FRONTEND_BASE_PATH, username), backend=client.NetworkingV1beta1IngressBackend( service_port=8888, service_name=name) )] ) ) ] ) ) # Creation of the Ingress in specified namespace networking_v1_beta1_api.create_namespaced_ingress( namespace=namespace, body=body ) except ApiException as e: error_msg = str(e).strip() logger.error(error_msg)
def create_ingress(namespace, ingress_name, host, path, service_name, service_port): body = client.NetworkingV1beta1Ingress( api_version="networking.k8s.io/v1beta1", kind="Ingress", metadata=client.V1ObjectMeta( name=ingress_name, annotations='{"kubernetes.io/ingress.class": "nginx"}'), spec=client.NetworkingV1beta1IngressSpec(rules=[ client.NetworkingV1beta1IngressRule( host=host, http=client.NetworkingV1beta1HTTPIngressRuleValue(paths=[ client.NetworkingV1beta1HTTPIngressPath( path=path, backend=client.NetworkingV1beta1IngressBackend( service_port=servcie_port, service_name=service_name)) ])) ])) myclient = client.AppsV1Api().NetworkingV1beta1Api() myclient.create_namespaced_ingress(namespace=namespace, body=body)
def create_ingress(networking_v1_beta1_api): body = client.NetworkingV1beta1Ingress( api_version="networking.k8s.io/v1beta1", kind="Ingress", metadata=client.V1ObjectMeta( name="minio-ingress", labels={"app": "minio"}, annotations={"nginx.ingress.kubernetes.io/rewrite-target": "/"}), spec=client.NetworkingV1beta1IngressSpec(rules=[ client.NetworkingV1beta1IngressRule( host="minio.kubernetes.local", http=client.NetworkingV1beta1HTTPIngressRuleValue(paths=[ client.NetworkingV1beta1HTTPIngressPath( path="/", backend=client.NetworkingV1beta1IngressBackend( service_port=9000, service_name="minio-service")) ])) ])) networking_v1_beta1_api.create_namespaced_ingress(namespace="default", body=body)
def create_ingress_object(name: str, service_name: str, service_port: int, user_id: str, host_uri: str) -> client.NetworkingV1beta1Ingress: webapi_host = host_uri body = client.NetworkingV1beta1Ingress( api_version="networking.k8s.io/v1beta1", kind="Ingress", metadata=client.V1ObjectMeta(name=name, annotations={ "proxy_set_header": "Upgrade $http_upgrade; Connection \"upgrade\"", "nginx.ingress.kubernetes.io/proxy-connect-timeout": "86400", "nginx.ingress.kubernetes.io/proxy-read-timeout": "86400", "nginx.ingress.kubernetes.io/proxy-send-timeout": "86400", "nginx.ingress.kubernetes.io/send-timeout": "86400", "nginx.ingress.kubernetes.io/proxy-body-size": "2000m", "nginx.ingress.kubernetes.io/enable-cors": "true", "nginx.ingress.kubernetes.io/websocket-services": service_name }), spec=client.NetworkingV1beta1IngressSpec( rules=[client.NetworkingV1beta1IngressRule( host=webapi_host, http=client.NetworkingV1beta1HTTPIngressRuleValue( paths=[client.NetworkingV1beta1HTTPIngressPath( path="/" + user_id + "/.*", backend=client.NetworkingV1beta1IngressBackend( service_port=service_port, service_name=service_name) )] ) ) ] ) ) return body
def update_ingress(self, ingress_name: str, ingress_body: dict): paths = self._update_ingress_paths(ingress_body) body = client.NetworkingV1beta1Ingress( api_version="networking.k8s.io/v1beta1", kind="Ingress", metadata=client.V1ObjectMeta( name=ingress_name, annotations={ "nginx.ingress.kubernetes.io/rewrite-target": "/" }), spec=client.NetworkingV1beta1IngressSpec(rules=[ client.NetworkingV1beta1IngressRule( http=client.NetworkingV1beta1HTTPIngressRuleValue( paths=paths)) ])) # check the current ingress list ingress_list = self.api_instance.list_namespaced_ingress_with_http_info( namespace='default') if ingress_list[1] != 200: raise ServiceRequestError("ingress response code is not 200") # get the ingress name of each ingress ingress_names = [ele.metadata.name for ele in ingress_list[0].items] # check if the ingress_name in the list if ingress_name in ingress_names: # if the ingress is exist, update it self.api_instance.replace_namespaced_ingress_with_http_info( name=ingress_name, namespace='default', body=body) else: # otherwise, create new one self.api_instance.create_namespaced_ingress_with_http_info( namespace='default', body=body)
def createOrPatchIngress(patch, spec, namespace, name): """Helper function to get API details and create or patch ingress. Args: * patch (Boolean): True to patch an existing Ingress; False to create a new Ingress. * spec (Dict): The spec from the API Resource showing the intent (or desired state) * namespace (String): The namespace for the API Custom Resource * name (String): The name of the API Custom Resource Returns: Dict: The updated apiStatus that will be put into the status field of the API resource. :meta private: """ client = kubernetes.client try: networking_v1_beta1_api = client.NetworkingV1beta1Api() hostname = None if 'hostname' in spec.keys(): hostname=spec['hostname'] ingress_spec=client.NetworkingV1beta1IngressSpec( rules=[client.NetworkingV1beta1IngressRule( host=hostname, http=client.NetworkingV1beta1HTTPIngressRuleValue( paths=[client.NetworkingV1beta1HTTPIngressPath( path=spec['path'], backend=client.NetworkingV1beta1IngressBackend( service_port=spec['port'], service_name=spec['implementation']) )] ) )] ) body = { "apiVersion": "networking.k8s.io/v1beta1", "kind": "Ingress", "metadata": { "name": name, "annotations": {"kubernetes.io/ingress.class": ingress_class} }, "spec": ingress_spec } # Make it our child: assign the namespace, name, labels, owner references, etc. kopf.adopt(body) logger.debug(f"[createOrPatchIngress/{namespace}/{name}] body (adopted): {body}") if patch == True: # patch the resource logger.debug(f"[createOrPatchIngress/{namespace}/{name}] Patching ingress with: {body}") ingressResource = networking_v1_beta1_api.patch_namespaced_ingress( name=name, namespace=namespace, body=body ) logger.debug(f"[createOrPatchIngress/{namespace}/{name}] ingressResource patched: {ingressResource}") logger.info(f"[createOrPatchIngress/{namespace}/{name}] ingress resource patched with name {name}") updateImplementationStatus(namespace, spec['implementation']) # update ingress status mydict = ingressResource.to_dict() apistatus = {'apiStatus': {"name": name, "uid": mydict['metadata']['uid'], "path": spec['path'], "port": spec['port'], "implementation": spec['implementation']}} if 'status' in mydict.keys(): if 'load_balancer' in mydict['status'].keys(): loadBalancer = mydict['status']['load_balancer'] if 'ingress' in loadBalancer.keys(): ingress = loadBalancer['ingress'] if isinstance(ingress, list): if len(ingress)>0: ingressTarget = ingress[0] apistatus = buildAPIStatus(spec, apistatus, ingressTarget) logger.debug(f"[createOrPatchIngress/{namespace}/{name}] apistatus = {apistatus}") return apistatus['apiStatus'] else: # create the resource logger.debug(f"[createOrPatchIngress/{namespace}/{name}] Creating ingress with: {body}") ingressResource = networking_v1_beta1_api.create_namespaced_ingress( namespace=namespace, body=body ) logger.debug(f"[createOrPatchIngress/{namespace}/{name}] ingressResource created: {ingressResource}") logger.info(f"[createOrPatchIngress/{namespace}/{name}] ingress resource created with name {name}") updateImplementationStatus(namespace, spec['implementation']) # Update the parent's status. mydict = ingressResource.to_dict() apistatus = {'apiStatus': {"name": name, "uid": mydict['metadata']['uid'], "path": spec['path'], "port": spec['port'], "implementation": spec['implementation']}} return apistatus['apiStatus'] except ApiException as e: logger.warning("Exception when calling NetworkingV1beta1Api: %s\n" % e) raise kopf.TemporaryError("Exception creating ingress.")
def create_site_ingress(site_name): k8s_settings = frappe.get_single("K8s Bench Settings") if ( not k8s_settings.namespace or not k8s_settings.wildcard_domain or not k8s_settings.wildcard_tls_secret_name or not k8s_settings.cert_manager_cluster_issuer ): not_set = "NOT_SET" out = { "namespace": k8s_settings.namespace or not_set, "wildcard_domain": k8s_settings.wildcard_domain or not_set, "wildcard_tls_secret_name": k8s_settings.wildcard_tls_secret_name or not_set, "cert_manager_cluster_issuer": k8s_settings.cert_manager_cluster_issuer or not_set, } frappe.local.response["http_status_code"] = 501 return out load_config() networking_v1_api = client.NetworkingV1beta1Api() body = client.NetworkingV1beta1Ingress() body.metadata = client.V1ObjectMeta( namespace=k8s_settings.namespace, name=site_name, annotations={ "cert-manager.io/cluster-issuer": k8s_settings.cert_manager_cluster_issuer }, ) body.status = client.V1JobStatus() body.spec = client.NetworkingV1beta1IngressSpec( rules=[ client.NetworkingV1beta1IngressRule( host=site_name, http=client.NetworkingV1beta1HTTPIngressRuleValue( paths=[ client.NetworkingV1beta1HTTPIngressPath( backend=client.NetworkingV1beta1IngressBackend( service_name=k8s_settings.service_name, service_port=80 ) ) ] ), ), ], tls=[ client.NetworkingV1beta1IngressTLS( hosts=[f"*.{k8s_settings.wildcard_domain}"], secret_name=k8s_settings.wildcard_tls_secret_name, ), ], ) try: ingress = networking_v1_api.create_namespaced_ingress( k8s_settings.namespace, body ) return to_dict(ingress) except (ApiException, Exception) as e: status_code = getattr(e, "status", 500) out = {"error": e, "params": {"site_name": site_name}} reason = getattr(e, "reason") if reason: out["reason"] = reason frappe.log_error( out, "Exception: NetworkingV1beta1Api->create_namespaced_ingress" ) frappe.local.response["http_status_code"] = status_code return out