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)
    # 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 #2
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
Exemple #3
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 #4
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
    )
 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))
Exemple #7
0
 def create_ingress(self, metadata: dict, spec: dict):
     request = client.NetworkingV1beta1Ingress(
         api_version='networking.k8s.io/v1beta1',
         kind='Ingress',
         metadata=metadata,
         spec=spec)
     try:
         self._networking.create_namespaced_ingress(namespace='default',
                                                    body=request)
     except ApiException as e:
         self._raise_runtime_error(e)
Exemple #8
0
 def deploy_ingress(
     self,
     target_service,
     port=None,
     title=None,
     ingress_labels=None,
     rewrite_path=True,
 ):
     ingress = self.get_ingress(ingress_labels)
     if not ingress:
         path = self.get_ingress_path(title)
         annotations = {}
         ingress_path = path
         if self.environment.ingress_class:
             annotations[
                 "kubernetes.io/ingress.class"] = self.environment.ingress_class
         if rewrite_path and self.environment.ingress_class:
             if self.environment.ingress_class == "nginx":
                 annotations[
                     "nginx.ingress.kubernetes.io/rewrite-target"] = "/$1"
                 ingress_path += "(.*)"
             elif self.environment.ingress_class == "haproxy":
                 # annotations["ingress.kubernetes.io/path-rewrite"] = "%s(.*) /\\1" % path
                 annotations["ingress.kubernetes.io/rewrite-target"] = "/"
         ingress = self.networking_api.create_namespaced_ingress(
             namespace=self.environment.namespace,
             body=kubernetes_client.NetworkingV1beta1Ingress(
                 api_version="networking.k8s.io/v1beta1",
                 kind="Ingress",
                 metadata=kubernetes_client.V1ObjectMeta(
                     name=self.generate_object_name(title),
                     namespace=self.environment.namespace,
                     labels=self.generate_object_labels(ingress_labels),
                     annotations=annotations),
                 spec=kubernetes_client.NetworkingV1beta1IngressSpec(rules=[
                     kubernetes_client.NetworkingV1beta1IngressRule(
                         http=kubernetes_client.
                         NetworkingV1beta1HTTPIngressRuleValue(paths=[
                             kubernetes_client.
                             NetworkingV1beta1HTTPIngressPath(
                                 path=ingress_path,
                                 backend=kubernetes_client.
                                 NetworkingV1beta1IngressBackend(
                                     service_name=target_service.metadata.
                                     name,
                                     service_port=port,
                                 ))
                         ])),
                 ], ),
             ),
         )
     return ingress
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 #10
0
    def test_create_ingress(self):
        self._networking_api.create_namespaced_ingress = Mock(
            side_effect=ApiException(500, 'Test'))

        ingress = client.NetworkingV1beta1Ingress(
            metadata=V1ObjectMeta(name='ingress'), )

        with self.assertRaises(api.ApiError) as e:
            create_ingress(ingress=ingress,
                           namespace='test',
                           core_api=self._networking_api)

        expected = ("Error when creating the ingress ingress: (500)\n"
                    "Reason: Test\n")
        self.assertEqual(expected, str(e.exception))
        self.assertEqual(400, e.exception.status_code)
Exemple #11
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 #12
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 #13
0
def create_k8s_ingress(namespace, name, urls, annotations={}, wait_for_seconds=DEFAULT_WAIT_TIME):
    networking_api.create_namespaced_ingress(
        namespace,
        k8s_client.NetworkingV1beta1Ingress(
            api_version='networking.k8s.io/v1beta1',
            kind='Ingress',
            metadata=k8s_client.V1ObjectMeta(
                name=name,
                annotations={f'{GROUP}/{k}': v for k,v in annotations.items()}
                ),
            spec=k8s_client.NetworkingV1beta1IngressSpec(
                rules=[
                    k8s_client.NetworkingV1beta1IngressRule(
                        host=url
                    ) for url in urls
                ]
            )
        )
    )

    time.sleep(wait_for_seconds)
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 #15
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)
Exemple #16
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
Exemple #17
0
 def create_or_update_ingress(self,
                              metadata,
                              spec,
                              name,
                              namespace='default'):
     request = client.NetworkingV1beta1Ingress(
         api_version='networking.k8s.io/v1beta1',
         kind='Ingress',
         metadata=metadata,
         spec=spec)
     try:
         self._networking.read_namespaced_ingress(name, namespace)
         # If the ingress already exists, then we use patch to replace it.
         # We don't use replace method because it requires `resourceVersion`.
         self._networking.patch_namespaced_ingress(name, namespace, request)
         return
     except ApiException as e:
         # 404 is expected if the ingress does not exist
         if e.status != HTTPStatus.NOT_FOUND:
             self._raise_runtime_error(e)
     try:
         self._networking.create_namespaced_ingress(namespace, request)
     except ApiException as e:
         self._raise_runtime_error(e)
    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 get_ingress(self, name, namespace='default'):
     return client.NetworkingV1beta1Ingress(
         api_version='networking.k8s.io/v1beta1',
         kind='Ingress',
         metadata=client.V1ObjectMeta(name=name, namespace=namespace),
         spec=client.NetworkingV1beta1IngressSpec())
Exemple #20
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