Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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
    )
Exemple #4
0
    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 get_obj(self):
     """
     :description: Generate ingress obj.
     """
     return client.NetworkingV1beta1Ingress(
         api_version=self.api_version,
         kind=self.kind,
         metadata=client.V1ObjectMeta(name=self.slug,
                                      annotations=self.annotations),
         spec=client.NetworkingV1beta1IngressSpec(
             selector=client.V1LabelSelector(match_labels=self.selector),
             rules=[
                 client.NetworkingV1beta1IngressRule(
                     host=self.hostname,
                     http=client.
                     NetworkingV1beta1HTTPIngressRuleValue(paths=[
                         client.NetworkingV1beta1HTTPIngressPath(
                             path=self.path,
                             backend=client.NetworkingV1beta1IngressBackend(
                                 service_port=self.target_service.port,
                                 service_name=self.target_service.slug),
                         )
                     ]),
                 )
             ],
         ),
     )
Exemple #6
0
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 _update_ingress_paths(self, ingress_body: dict) -> list:
        paths = list()
        for path_info in ingress_body["spec"]["rules"][0]["http"]["paths"]:
            path_obj = client.NetworkingV1beta1HTTPIngressPath(
                path=path_info["path"],
                backend=client.NetworkingV1beta1IngressBackend(
                    service_port=path_info["backend"]["servicePort"],
                    service_name=path_info["backend"]["serviceName"]))
            paths.append(path_obj)

        return paths
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)
Exemple #9
0
 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))
                 ]))
         ]))
Exemple #10
0
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)
Exemple #11
0
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)
Exemple #13
0
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 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.")                  
Exemple #15
0
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