Search in sources :

Example 1 with HTTPIngressPath

use of io.fabric8.kubernetes.api.model.networking.v1.HTTPIngressPath in project curiostack by curioswitch.

the class DeployPodTask method exec.

@TaskAction
public void exec() {
    ImmutableDeploymentExtension config = getProject().getExtensions().getByType(DeploymentExtension.class);
    final ImmutableDeploymentConfiguration deploymentConfig = config.getTypes().getByName(type);
    ImmutableGcloudExtension gcloud = getProject().getRootProject().getExtensions().getByType(GcloudExtension.class);
    ImmutableList.Builder<EnvVar> envVars = ImmutableList.<EnvVar>builder().addAll(deploymentConfig.envVars().entrySet().stream().map((entry) -> new EnvVar(entry.getKey(), entry.getValue(), null))::iterator).addAll(deploymentConfig.secretEnvVars().entrySet().stream().map((entry) -> new EnvVar(entry.getKey(), null, new EnvVarSourceBuilder().withSecretKeyRef(new SecretKeySelectorBuilder().withName(entry.getValue().get(0)).withKey(entry.getValue().get(1)).build()).build()))::iterator);
    if (!deploymentConfig.envVars().containsKey("JAVA_OPTS")) {
        int heapSize = deploymentConfig.jvmHeapMb();
        StringBuilder javaOpts = new StringBuilder();
        javaOpts.append("--add-opens java.base/jdk.internal.misc=ALL-UNNAMED ").append("--add-opens jdk.unsupported/sun.misc=ALL-UNNAMED ").append("-Xms").append(heapSize).append("m ").append("-Xmx").append(heapSize).append("m ").append("-Dconfig.resource=application-").append(type).append(".conf ").append("-Dmonitoring.stackdriverProjectId=").append(gcloud.clusterProject()).append(" ").append("-Dmonitoring.serverName=").append(deploymentConfig.deploymentName()).append(" ");
        if (!deploymentConfig.request()) {
            int numCpus = (int) Math.ceil(Double.parseDouble(deploymentConfig.cpu()));
            int numWorkers = numCpus * 2;
            javaOpts.append("-XX:ParallelGCThreads=").append(numCpus).append(" ").append("-Dcom.linecorp.armeria.numCommonWorkers=").append(numWorkers).append(" ").append("-Dio.netty.availableProcessors=").append(numCpus).append(" ");
        }
        if (!type.equals("prod")) {
            javaOpts.append("-Dcom.linecorp.armeria.verboseExceptions=true ");
        }
        envVars.add(new EnvVar("JAVA_OPTS", javaOpts.toString(), null));
    }
    Map<String, Quantity> resources = ImmutableMap.of("cpu", new Quantity(deploymentConfig.cpu()), "memory", new Quantity(deploymentConfig.memoryMb() + "Mi"));
    Deployment deployment = new DeploymentBuilder().withMetadata(new ObjectMetaBuilder().withNamespace(deploymentConfig.namespace()).withName(deploymentConfig.deploymentName()).build()).withSpec(new DeploymentSpecBuilder().withReplicas(deploymentConfig.replicas()).withStrategy(new DeploymentStrategyBuilder().withType("RollingUpdate").withRollingUpdate(new RollingUpdateDeploymentBuilder().withNewMaxUnavailable(0).build()).build()).withSelector(new LabelSelectorBuilder().withMatchLabels(ImmutableMap.of("name", deploymentConfig.deploymentName())).build()).withTemplate(new PodTemplateSpecBuilder().withMetadata(new ObjectMetaBuilder().withLabels(ImmutableMap.of("name", deploymentConfig.deploymentName(), "revision", System.getenv().getOrDefault("REVISION_ID", "none"))).withAnnotations(ImmutableMap.<String, String>builder().put("prometheus.io/scrape", "true").put("prometheus.io/scheme", "https").put("prometheus.io/path", "/internal/metrics").put("prometheus.io/port", String.valueOf(deploymentConfig.containerPort())).build()).build()).withSpec(new PodSpecBuilder().withContainers(new ContainerBuilder().withResources(new ResourceRequirementsBuilder().withLimits(!deploymentConfig.request() ? resources : ImmutableMap.of()).withRequests(deploymentConfig.request() ? resources : ImmutableMap.of()).build()).withImage(deploymentConfig.image()).withName(deploymentConfig.deploymentName()).withEnv(envVars.build()).withImagePullPolicy("Always").withReadinessProbe(createProbe(deploymentConfig, Duration.ofSeconds(5))).withLivenessProbe(createProbe(deploymentConfig, Duration.ofSeconds(15))).withPorts(ImmutableList.of(new ContainerPortBuilder().withContainerPort(deploymentConfig.containerPort()).withName("http").build())).withVolumeMounts(new VolumeMountBuilder().withName("tls").withMountPath("/etc/tls").withReadOnly(true).build(), new VolumeMountBuilder().withName("rpcacls").withMountPath("/etc/rpcacls").withReadOnly(true).build()).build()).withVolumes(new VolumeBuilder().withName("tls").withSecret(new SecretVolumeSourceBuilder().withSecretName("server-tls").build()).build(), new VolumeBuilder().withName("rpcacls").withConfigMap(new ConfigMapVolumeSourceBuilder().withName("rpcacls").build()).build()).build()).build()).build()).build();
    KubernetesClient client = new DefaultKubernetesClient();
    Service service = new ServiceBuilder().withMetadata(new ObjectMetaBuilder().withName(deploymentConfig.deploymentName()).withNamespace(deploymentConfig.namespace()).withAnnotations(ImmutableMap.<String, String>builder().put("service.alpha.kubernetes.io/app-protocols", "{\"https\":\"HTTPS\"}").put("prometheus.io/scrape", "true").put("prometheus.io/scheme", "https").put("prometheus.io/path", "/internal/metrics").put("prometheus.io/port", String.valueOf(deploymentConfig.containerPort())).put("prometheus.io/probe", "true").build()).build()).withSpec(createServiceSpec(deploymentConfig)).build();
    Map<String, Service> additionalServices = new HashMap<>();
    for (String path : deploymentConfig.additionalServicePaths()) {
        String sanitizedPath = path;
        if (sanitizedPath.endsWith("/*")) {
            sanitizedPath = sanitizedPath.substring(0, path.length() - 2);
        }
        String serviceName = deploymentConfig.deploymentName() + sanitizedPath.replace('/', '-');
        additionalServices.put(path, new ServiceBuilder().withMetadata(new ObjectMetaBuilder().withName(serviceName).withNamespace(deploymentConfig.namespace()).withAnnotations(ImmutableMap.of("service.alpha.kubernetes.io/app-protocols", "{\"https\":\"HTTPS\"}")).build()).withSpec(createServiceSpec(deploymentConfig)).build());
    }
    client.resource(deployment).createOrReplace();
    deployService(service, client);
    additionalServices.values().forEach(s -> deployService(s, client));
    if (deploymentConfig.externalHost() != null) {
        List<HTTPIngressPath> ingressPaths = new ArrayList<>();
        additionalServices.forEach((path, s) -> ingressPaths.add(createIngressPath(path, s.getMetadata().getName(), deploymentConfig)));
        ingressPaths.add(createIngressPath("/*", deploymentConfig.deploymentName(), deploymentConfig));
        Ingress ingress = new IngressBuilder().withMetadata(new ObjectMetaBuilder().withNamespace(deploymentConfig.namespace()).withName(deploymentConfig.deploymentName()).withAnnotations(ImmutableMap.of("kubernetes.io/tls-acme", "true", "kubernetes.io/ingress.class", "gce")).build()).withSpec(new IngressSpecBuilder().withTls(new IngressTLSBuilder().withSecretName(deploymentConfig.deploymentName() + "-tls").withHosts(deploymentConfig.externalHost()).build()).withRules(new IngressRuleBuilder().withHost(deploymentConfig.externalHost()).withHttp(new HTTPIngressRuleValueBuilder().withPaths(ingressPaths).build()).build()).build()).build();
        client.resource(ingress).createOrReplace();
    }
}
Also used : Quantity(io.fabric8.kubernetes.api.model.Quantity) ConfigMapVolumeSourceBuilder(io.fabric8.kubernetes.api.model.ConfigMapVolumeSourceBuilder) IntOrString(io.fabric8.kubernetes.api.model.IntOrString) IngressRuleBuilder(io.fabric8.kubernetes.api.model.extensions.IngressRuleBuilder) Deployment(io.fabric8.kubernetes.api.model.extensions.Deployment) ImmutableDeploymentExtension(org.curioswitch.gradle.plugins.curioserver.ImmutableDeploymentExtension) ImmutableDeploymentConfiguration(org.curioswitch.gradle.plugins.curioserver.ImmutableDeploymentExtension.ImmutableDeploymentConfiguration) TaskAction(org.gradle.api.tasks.TaskAction) VolumeMountBuilder(io.fabric8.kubernetes.api.model.VolumeMountBuilder) Duration(java.time.Duration) Map(java.util.Map) ContainerBuilder(io.fabric8.kubernetes.api.model.ContainerBuilder) DefaultTask(org.gradle.api.DefaultTask) DefaultKubernetesClient(io.fabric8.kubernetes.client.DefaultKubernetesClient) ServiceBuilder(io.fabric8.kubernetes.api.model.ServiceBuilder) SecretVolumeSourceBuilder(io.fabric8.kubernetes.api.model.SecretVolumeSourceBuilder) IngressBackendBuilder(io.fabric8.kubernetes.api.model.extensions.IngressBackendBuilder) LabelSelectorBuilder(io.fabric8.kubernetes.api.model.LabelSelectorBuilder) ImmutableMap(com.google.common.collect.ImmutableMap) HTTPIngressRuleValueBuilder(io.fabric8.kubernetes.api.model.extensions.HTTPIngressRuleValueBuilder) Ingress(io.fabric8.kubernetes.api.model.extensions.Ingress) VolumeBuilder(io.fabric8.kubernetes.api.model.VolumeBuilder) List(java.util.List) RollingUpdateDeploymentBuilder(io.fabric8.kubernetes.api.model.extensions.RollingUpdateDeploymentBuilder) DeploymentBuilder(io.fabric8.kubernetes.api.model.extensions.DeploymentBuilder) GcloudExtension(org.curioswitch.gradle.plugins.gcloud.GcloudExtension) HTTPGetActionBuilder(io.fabric8.kubernetes.api.model.HTTPGetActionBuilder) ProbeBuilder(io.fabric8.kubernetes.api.model.ProbeBuilder) ServiceSpec(io.fabric8.kubernetes.api.model.ServiceSpec) EnvVar(io.fabric8.kubernetes.api.model.EnvVar) ImmutableGcloudExtension(org.curioswitch.gradle.plugins.gcloud.ImmutableGcloudExtension) ResourceRequirementsBuilder(io.fabric8.kubernetes.api.model.ResourceRequirementsBuilder) IngressTLSBuilder(io.fabric8.kubernetes.api.model.extensions.IngressTLSBuilder) ServicePortBuilder(io.fabric8.kubernetes.api.model.ServicePortBuilder) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) PodSpecBuilder(io.fabric8.kubernetes.api.model.PodSpecBuilder) EnvVarSourceBuilder(io.fabric8.kubernetes.api.model.EnvVarSourceBuilder) ServiceSpecBuilder(io.fabric8.kubernetes.api.model.ServiceSpecBuilder) Service(io.fabric8.kubernetes.api.model.Service) HTTPIngressPathBuilder(io.fabric8.kubernetes.api.model.extensions.HTTPIngressPathBuilder) HTTPIngressPath(io.fabric8.kubernetes.api.model.extensions.HTTPIngressPath) ObjectMetaBuilder(io.fabric8.kubernetes.api.model.ObjectMetaBuilder) DeploymentExtension(org.curioswitch.gradle.plugins.curioserver.DeploymentExtension) PodTemplateSpecBuilder(io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder) Probe(io.fabric8.kubernetes.api.model.Probe) IngressBuilder(io.fabric8.kubernetes.api.model.extensions.IngressBuilder) SecretKeySelectorBuilder(io.fabric8.kubernetes.api.model.SecretKeySelectorBuilder) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) DeploymentSpecBuilder(io.fabric8.kubernetes.api.model.extensions.DeploymentSpecBuilder) ContainerPortBuilder(io.fabric8.kubernetes.api.model.ContainerPortBuilder) DeploymentStrategyBuilder(io.fabric8.kubernetes.api.model.extensions.DeploymentStrategyBuilder) IngressSpecBuilder(io.fabric8.kubernetes.api.model.extensions.IngressSpecBuilder) IngressRuleBuilder(io.fabric8.kubernetes.api.model.extensions.IngressRuleBuilder) DeploymentSpecBuilder(io.fabric8.kubernetes.api.model.extensions.DeploymentSpecBuilder) ImmutableGcloudExtension(org.curioswitch.gradle.plugins.gcloud.ImmutableGcloudExtension) HashMap(java.util.HashMap) ImmutableList(com.google.common.collect.ImmutableList) ResourceRequirementsBuilder(io.fabric8.kubernetes.api.model.ResourceRequirementsBuilder) ArrayList(java.util.ArrayList) Deployment(io.fabric8.kubernetes.api.model.extensions.Deployment) IntOrString(io.fabric8.kubernetes.api.model.IntOrString) VolumeBuilder(io.fabric8.kubernetes.api.model.VolumeBuilder) HTTPIngressPath(io.fabric8.kubernetes.api.model.extensions.HTTPIngressPath) ServiceBuilder(io.fabric8.kubernetes.api.model.ServiceBuilder) EnvVarSourceBuilder(io.fabric8.kubernetes.api.model.EnvVarSourceBuilder) ContainerBuilder(io.fabric8.kubernetes.api.model.ContainerBuilder) HTTPIngressRuleValueBuilder(io.fabric8.kubernetes.api.model.extensions.HTTPIngressRuleValueBuilder) RollingUpdateDeploymentBuilder(io.fabric8.kubernetes.api.model.extensions.RollingUpdateDeploymentBuilder) ConfigMapVolumeSourceBuilder(io.fabric8.kubernetes.api.model.ConfigMapVolumeSourceBuilder) EnvVar(io.fabric8.kubernetes.api.model.EnvVar) IngressTLSBuilder(io.fabric8.kubernetes.api.model.extensions.IngressTLSBuilder) ImmutableDeploymentConfiguration(org.curioswitch.gradle.plugins.curioserver.ImmutableDeploymentExtension.ImmutableDeploymentConfiguration) SecretKeySelectorBuilder(io.fabric8.kubernetes.api.model.SecretKeySelectorBuilder) PodSpecBuilder(io.fabric8.kubernetes.api.model.PodSpecBuilder) LabelSelectorBuilder(io.fabric8.kubernetes.api.model.LabelSelectorBuilder) SecretVolumeSourceBuilder(io.fabric8.kubernetes.api.model.SecretVolumeSourceBuilder) DefaultKubernetesClient(io.fabric8.kubernetes.client.DefaultKubernetesClient) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) Quantity(io.fabric8.kubernetes.api.model.Quantity) Service(io.fabric8.kubernetes.api.model.Service) Ingress(io.fabric8.kubernetes.api.model.extensions.Ingress) DeploymentStrategyBuilder(io.fabric8.kubernetes.api.model.extensions.DeploymentStrategyBuilder) ObjectMetaBuilder(io.fabric8.kubernetes.api.model.ObjectMetaBuilder) VolumeMountBuilder(io.fabric8.kubernetes.api.model.VolumeMountBuilder) IngressBuilder(io.fabric8.kubernetes.api.model.extensions.IngressBuilder) ImmutableDeploymentExtension(org.curioswitch.gradle.plugins.curioserver.ImmutableDeploymentExtension) IngressSpecBuilder(io.fabric8.kubernetes.api.model.extensions.IngressSpecBuilder) PodTemplateSpecBuilder(io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder) ContainerPortBuilder(io.fabric8.kubernetes.api.model.ContainerPortBuilder) DefaultKubernetesClient(io.fabric8.kubernetes.client.DefaultKubernetesClient) RollingUpdateDeploymentBuilder(io.fabric8.kubernetes.api.model.extensions.RollingUpdateDeploymentBuilder) DeploymentBuilder(io.fabric8.kubernetes.api.model.extensions.DeploymentBuilder) TaskAction(org.gradle.api.tasks.TaskAction)

Example 2 with HTTPIngressPath

use of io.fabric8.kubernetes.api.model.networking.v1.HTTPIngressPath in project fabric8 by jboss-fuse.

the class KubernetesHelper method getServiceURL.

/**
 * Returns the URL to access the service; using the environment variables, routes
 * or service clusterIP address
 *
 * @throws IllegalArgumentException if the URL cannot be found for the serviceName and namespace
 */
public static String getServiceURL(KubernetesClient client, String serviceName, String serviceNamespace, String serviceProtocol, String servicePortName, boolean serviceExternal) {
    Service srv = null;
    String serviceHost = KubernetesServices.serviceToHostOrBlank(serviceName);
    String servicePort = KubernetesServices.serviceToPortOrBlank(serviceName, servicePortName);
    String serviceProto = serviceProtocol != null ? serviceProtocol : KubernetesServices.serviceToProtocol(serviceName, servicePort);
    // Use specified or fallback namespace.
    String actualNamespace = Strings.isNotBlank(serviceNamespace) ? serviceNamespace : client.getNamespace();
    // 1. Inside Kubernetes: Services as ENV vars
    if (!serviceExternal && Strings.isNotBlank(serviceHost) && Strings.isNotBlank(servicePort) && Strings.isNotBlank(serviceProtocol)) {
        return serviceProtocol + "://" + serviceHost + ":" + servicePort;
    // 2. Anywhere: When namespace is passed System / Env var. Mostly needed for integration tests.
    } else if (Strings.isNotBlank(actualNamespace)) {
        try {
            srv = client.services().inNamespace(actualNamespace).withName(serviceName).get();
        } catch (Exception e) {
            LOGGER.warn("Could not lookup service:" + serviceName + " in namespace:" + actualNamespace + ", due to: " + e.getMessage());
        }
    }
    if (srv == null) {
        // lets try use environment variables
        String hostAndPort = Systems.getServiceHostAndPort(serviceName, "", "");
        if (!hostAndPort.startsWith(":")) {
            return serviceProto + "://" + hostAndPort;
        }
    }
    if (srv == null) {
        throw new IllegalArgumentException("No kubernetes service could be found for name: " + serviceName + " in namespace: " + actualNamespace);
    }
    String answer = getOrCreateAnnotations(srv).get(Annotations.Service.EXPOSE_URL);
    if (Strings.isNotBlank(answer)) {
        return answer;
    }
    try {
        if (Strings.isNullOrBlank(servicePortName) && isOpenShift(client)) {
            OpenShiftClient openShiftClient = client.adapt(OpenShiftClient.class);
            Route route = openShiftClient.routes().inNamespace(actualNamespace).withName(serviceName).get();
            if (route != null) {
                return (serviceProto + "://" + route.getSpec().getHost()).toLowerCase();
            }
        }
    } catch (KubernetesClientException e) {
        if (e.getCode() == 403) {
            LOGGER.warn("Could not lookup route:" + serviceName + " in namespace:" + actualNamespace + ", due to: " + e.getMessage());
        } else {
            throw e;
        }
    }
    ServicePort port = findServicePortByName(srv, servicePortName);
    if (port == null) {
        throw new RuntimeException("Couldn't find port: " + servicePortName + " for service:" + serviceName);
    }
    String clusterIP = srv.getSpec().getClusterIP();
    if ("None".equals(clusterIP)) {
        throw new IllegalStateException("Service: " + serviceName + " in namespace:" + serviceNamespace + "is head-less. Search for endpoints instead.");
    }
    Integer portNumber = port.getPort();
    if (Strings.isNullOrBlank(clusterIP)) {
        IngressList ingresses = client.extensions().ingresses().inNamespace(serviceNamespace).list();
        if (ingresses != null) {
            List<Ingress> items = ingresses.getItems();
            if (items != null) {
                for (Ingress item : items) {
                    String ns = getNamespace(item);
                    if (Objects.equal(serviceNamespace, ns)) {
                        IngressSpec spec = item.getSpec();
                        if (spec != null) {
                            List<IngressRule> rules = spec.getRules();
                            List<IngressTLS> tls = spec.getTls();
                            if (rules != null) {
                                for (IngressRule rule : rules) {
                                    HTTPIngressRuleValue http = rule.getHttp();
                                    if (http != null) {
                                        List<HTTPIngressPath> paths = http.getPaths();
                                        if (paths != null) {
                                            for (HTTPIngressPath path : paths) {
                                                IngressBackend backend = path.getBackend();
                                                if (backend != null) {
                                                    String backendServiceName = backend.getServiceName();
                                                    if (serviceName.equals(backendServiceName) && portsMatch(port, backend.getServicePort())) {
                                                        String pathPostfix = path.getPath();
                                                        if (tls != null) {
                                                            for (IngressTLS tlsHost : tls) {
                                                                List<String> hosts = tlsHost.getHosts();
                                                                if (hosts != null) {
                                                                    for (String host : hosts) {
                                                                        if (Strings.isNotBlank(host)) {
                                                                            if (Strings.isNullOrBlank(pathPostfix)) {
                                                                                pathPostfix = "/";
                                                                            }
                                                                            return "https://" + URLUtils.pathJoin(host, pathPostfix);
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        answer = rule.getHost();
                                                        if (Strings.isNotBlank(answer)) {
                                                            if (Strings.isNullOrBlank(pathPostfix)) {
                                                                pathPostfix = "/";
                                                            }
                                                            return "http://" + URLUtils.pathJoin(answer, pathPostfix);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        // lets try use the status on GKE
        ServiceStatus status = srv.getStatus();
        if (status != null) {
            LoadBalancerStatus loadBalancerStatus = status.getLoadBalancer();
            if (loadBalancerStatus != null) {
                List<LoadBalancerIngress> loadBalancerIngresses = loadBalancerStatus.getIngress();
                if (loadBalancerIngresses != null) {
                    for (LoadBalancerIngress loadBalancerIngress : loadBalancerIngresses) {
                        String ip = loadBalancerIngress.getIp();
                        if (Strings.isNotBlank(ip)) {
                            clusterIP = ip;
                            break;
                        }
                    }
                }
            }
        }
    }
    if (Strings.isNullOrBlank(clusterIP)) {
        // on vanilla kubernetes we can use nodePort to access things externally
        boolean found = false;
        Integer nodePort = port.getNodePort();
        if (nodePort != null) {
            try {
                NodeList nodeList = client.nodes().list();
                if (nodeList != null) {
                    List<Node> items = nodeList.getItems();
                    if (items != null) {
                        for (Node item : items) {
                            NodeStatus status = item.getStatus();
                            if (!found && status != null) {
                                List<NodeAddress> addresses = status.getAddresses();
                                if (addresses != null) {
                                    for (NodeAddress address : addresses) {
                                        String ip = address.getAddress();
                                        if (Strings.isNotBlank(ip)) {
                                            clusterIP = ip;
                                            portNumber = nodePort;
                                            found = true;
                                            break;
                                        }
                                    }
                                }
                            }
                            if (!found) {
                                NodeSpec spec = item.getSpec();
                                if (spec != null) {
                                    clusterIP = spec.getExternalID();
                                    if (Strings.isNotBlank(clusterIP)) {
                                        portNumber = nodePort;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                // ignore could not find a node!
                LOG.warn("Could not find a node!: " + e, e);
            }
        }
    }
    return (serviceProto + "://" + clusterIP + ":" + portNumber).toLowerCase();
}
Also used : JsonNode(com.fasterxml.jackson.databind.JsonNode) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) IngressList(io.fabric8.kubernetes.api.model.extensions.IngressList) HTTPIngressPath(io.fabric8.kubernetes.api.model.extensions.HTTPIngressPath) IngressSpec(io.fabric8.kubernetes.api.model.extensions.IngressSpec) IngressRule(io.fabric8.kubernetes.api.model.extensions.IngressRule) HTTPIngressRuleValue(io.fabric8.kubernetes.api.model.extensions.HTTPIngressRuleValue) Route(io.fabric8.openshift.api.model.Route) Ingress(io.fabric8.kubernetes.api.model.extensions.Ingress) SSLHandshakeException(javax.net.ssl.SSLHandshakeException) SSLException(javax.net.ssl.SSLException) TextParseException(org.xbill.DNS.TextParseException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) ParseException(java.text.ParseException) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException) SSLProtocolException(javax.net.ssl.SSLProtocolException) SSLKeyException(javax.net.ssl.SSLKeyException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) SSLPeerUnverifiedException(javax.net.ssl.SSLPeerUnverifiedException) DefaultOpenShiftClient(io.fabric8.openshift.client.DefaultOpenShiftClient) OpenShiftClient(io.fabric8.openshift.client.OpenShiftClient) IngressTLS(io.fabric8.kubernetes.api.model.extensions.IngressTLS) IngressBackend(io.fabric8.kubernetes.api.model.extensions.IngressBackend) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException)

Example 3 with HTTPIngressPath

use of io.fabric8.kubernetes.api.model.networking.v1.HTTPIngressPath in project fabric8-maven-plugin by fabric8io.

the class ApplyMojo method createIngressForService.

private Ingress createIngressForService(String routeDomainPostfix, String namespace, Service service) {
    Ingress ingress = null;
    String serviceName = KubernetesHelper.getName(service);
    ServiceSpec serviceSpec = service.getSpec();
    if (serviceSpec != null && Strings.isNotBlank(serviceName) && shouldCreateExternalURLForService(service, serviceName)) {
        String ingressId = serviceName;
        String host = "";
        if (Strings.isNotBlank(routeDomainPostfix)) {
            host = serviceName + "." + namespace + "." + Strings.stripPrefix(routeDomainPostfix, ".");
        }
        List<HTTPIngressPath> paths = new ArrayList<>();
        List<ServicePort> ports = serviceSpec.getPorts();
        if (ports != null) {
            for (ServicePort port : ports) {
                Integer portNumber = port.getPort();
                if (portNumber != null) {
                    HTTPIngressPath path = new HTTPIngressPathBuilder().withNewBackend().withServiceName(serviceName).withServicePort(createIntOrString(portNumber.intValue())).endBackend().build();
                    paths.add(path);
                }
            }
        }
        if (paths.isEmpty()) {
            return ingress;
        }
        ingress = new IngressBuilder().withNewMetadata().withName(ingressId).withNamespace(namespace).endMetadata().withNewSpec().addNewRule().withHost(host).withNewHttp().withPaths(paths).endHttp().endRule().endSpec().build();
        String json;
        try {
            json = KubernetesHelper.toJson(ingress);
        } catch (JsonProcessingException e) {
            json = e.getMessage() + ". object: " + ingress;
        }
        log.debug("Created ingress: " + json);
    }
    return ingress;
}
Also used : ServicePort(io.fabric8.kubernetes.api.model.ServicePort) IngressBuilder(io.fabric8.kubernetes.api.model.extensions.IngressBuilder) ServiceSpec(io.fabric8.kubernetes.api.model.ServiceSpec) ArrayList(java.util.ArrayList) Ingress(io.fabric8.kubernetes.api.model.extensions.Ingress) HTTPIngressPathBuilder(io.fabric8.kubernetes.api.model.extensions.HTTPIngressPathBuilder) KubernetesHelper.createIntOrString(io.fabric8.kubernetes.api.KubernetesHelper.createIntOrString) HTTPIngressPath(io.fabric8.kubernetes.api.model.extensions.HTTPIngressPath) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Example 4 with HTTPIngressPath

use of io.fabric8.kubernetes.api.model.networking.v1.HTTPIngressPath in project fabric8-maven-plugin by fabric8io.

the class ApplyMojo method serviceHasIngressRule.

/**
 * Returns true if there is an existing ingress rule for the given service
 */
private boolean serviceHasIngressRule(List<Ingress> ingresses, Service service) {
    String serviceName = KubernetesHelper.getName(service);
    for (Ingress ingress : ingresses) {
        IngressSpec spec = ingress.getSpec();
        if (spec == null) {
            break;
        }
        List<IngressRule> rules = spec.getRules();
        if (rules == null) {
            break;
        }
        for (IngressRule rule : rules) {
            HTTPIngressRuleValue http = rule.getHttp();
            if (http == null) {
                break;
            }
            List<HTTPIngressPath> paths = http.getPaths();
            if (paths == null) {
                break;
            }
            for (HTTPIngressPath path : paths) {
                IngressBackend backend = path.getBackend();
                if (backend == null) {
                    break;
                }
                if (Objects.equals(serviceName, backend.getServiceName())) {
                    return true;
                }
            }
        }
    }
    return false;
}
Also used : IngressSpec(io.fabric8.kubernetes.api.model.extensions.IngressSpec) IngressRule(io.fabric8.kubernetes.api.model.extensions.IngressRule) HTTPIngressRuleValue(io.fabric8.kubernetes.api.model.extensions.HTTPIngressRuleValue) Ingress(io.fabric8.kubernetes.api.model.extensions.Ingress) KubernetesHelper.createIntOrString(io.fabric8.kubernetes.api.KubernetesHelper.createIntOrString) HTTPIngressPath(io.fabric8.kubernetes.api.model.extensions.HTTPIngressPath) IngressBackend(io.fabric8.kubernetes.api.model.extensions.IngressBackend)

Example 5 with HTTPIngressPath

use of io.fabric8.kubernetes.api.model.networking.v1.HTTPIngressPath in project fabric8 by fabric8io.

the class KubernetesHelper method getServiceURL.

/**
 * Returns the URL to access the service; using the environment variables, routes
 * or service clusterIP address
 *
 * @throws IllegalArgumentException if the URL cannot be found for the serviceName and namespace
 */
public static String getServiceURL(KubernetesClient client, String serviceName, String serviceNamespace, String serviceProtocol, String servicePortName, boolean serviceExternal) {
    Service srv = null;
    String serviceHost = KubernetesServices.serviceToHostOrBlank(serviceName);
    String servicePort = KubernetesServices.serviceToPortOrBlank(serviceName, servicePortName);
    String serviceProto = serviceProtocol != null ? serviceProtocol : KubernetesServices.serviceToProtocol(serviceName, servicePort);
    // Use specified or fallback namespace.
    String actualNamespace = Strings.isNotBlank(serviceNamespace) ? serviceNamespace : client.getNamespace();
    // 1. Inside Kubernetes: Services as ENV vars
    if (!serviceExternal && Strings.isNotBlank(serviceHost) && Strings.isNotBlank(servicePort) && Strings.isNotBlank(serviceProtocol)) {
        return serviceProtocol + "://" + serviceHost + ":" + servicePort;
    // 2. Anywhere: When namespace is passed System / Env var. Mostly needed for integration tests.
    } else if (Strings.isNotBlank(actualNamespace)) {
        try {
            srv = client.services().inNamespace(actualNamespace).withName(serviceName).get();
        } catch (Exception e) {
            LOGGER.warn("Could not lookup service:" + serviceName + " in namespace:" + actualNamespace + ", due to: " + e.getMessage());
        }
    }
    if (srv == null) {
        // lets try use environment variables
        String hostAndPort = Systems.getServiceHostAndPort(serviceName, "", "");
        if (!hostAndPort.startsWith(":")) {
            return serviceProto + "://" + hostAndPort;
        }
    }
    if (srv == null) {
        throw new IllegalArgumentException("No kubernetes service could be found for name: " + serviceName + " in namespace: " + actualNamespace);
    }
    String answer = getOrCreateAnnotations(srv).get(Annotations.Service.EXPOSE_URL);
    if (Strings.isNotBlank(answer)) {
        return answer;
    }
    try {
        if (Strings.isNullOrBlank(servicePortName) && isOpenShift(client)) {
            OpenShiftClient openShiftClient = client.adapt(OpenShiftClient.class);
            Route route = openShiftClient.routes().inNamespace(actualNamespace).withName(serviceName).get();
            if (route != null) {
                return (serviceProto + "://" + route.getSpec().getHost()).toLowerCase();
            }
        }
    } catch (KubernetesClientException e) {
        if (e.getCode() == 403) {
            LOGGER.warn("Could not lookup route:" + serviceName + " in namespace:" + actualNamespace + ", due to: " + e.getMessage());
        } else {
            throw e;
        }
    }
    ServicePort port = findServicePortByName(srv, servicePortName);
    if (port == null) {
        throw new RuntimeException("Couldn't find port: " + servicePortName + " for service:" + serviceName);
    }
    String clusterIP = srv.getSpec().getClusterIP();
    if ("None".equals(clusterIP)) {
        throw new IllegalStateException("Service: " + serviceName + " in namespace:" + serviceNamespace + "is head-less. Search for endpoints instead.");
    }
    Integer portNumber = port.getPort();
    if (Strings.isNullOrBlank(clusterIP)) {
        IngressList ingresses = client.extensions().ingresses().inNamespace(serviceNamespace).list();
        if (ingresses != null) {
            List<Ingress> items = ingresses.getItems();
            if (items != null) {
                for (Ingress item : items) {
                    String ns = getNamespace(item);
                    if (Objects.equal(serviceNamespace, ns)) {
                        IngressSpec spec = item.getSpec();
                        if (spec != null) {
                            List<IngressRule> rules = spec.getRules();
                            List<IngressTLS> tls = spec.getTls();
                            if (rules != null) {
                                for (IngressRule rule : rules) {
                                    HTTPIngressRuleValue http = rule.getHttp();
                                    if (http != null) {
                                        List<HTTPIngressPath> paths = http.getPaths();
                                        if (paths != null) {
                                            for (HTTPIngressPath path : paths) {
                                                IngressBackend backend = path.getBackend();
                                                if (backend != null) {
                                                    String backendServiceName = backend.getServiceName();
                                                    if (serviceName.equals(backendServiceName) && portsMatch(port, backend.getServicePort())) {
                                                        String pathPostfix = path.getPath();
                                                        if (tls != null) {
                                                            for (IngressTLS tlsHost : tls) {
                                                                List<String> hosts = tlsHost.getHosts();
                                                                if (hosts != null) {
                                                                    for (String host : hosts) {
                                                                        if (Strings.isNotBlank(host)) {
                                                                            if (Strings.isNullOrBlank(pathPostfix)) {
                                                                                pathPostfix = "/";
                                                                            }
                                                                            return "https://" + URLUtils.pathJoin(host, pathPostfix);
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        answer = rule.getHost();
                                                        if (Strings.isNotBlank(answer)) {
                                                            if (Strings.isNullOrBlank(pathPostfix)) {
                                                                pathPostfix = "/";
                                                            }
                                                            return "http://" + URLUtils.pathJoin(answer, pathPostfix);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        // lets try use the status on GKE
        ServiceStatus status = srv.getStatus();
        if (status != null) {
            LoadBalancerStatus loadBalancerStatus = status.getLoadBalancer();
            if (loadBalancerStatus != null) {
                List<LoadBalancerIngress> loadBalancerIngresses = loadBalancerStatus.getIngress();
                if (loadBalancerIngresses != null) {
                    for (LoadBalancerIngress loadBalancerIngress : loadBalancerIngresses) {
                        String ip = loadBalancerIngress.getIp();
                        if (Strings.isNotBlank(ip)) {
                            clusterIP = ip;
                            break;
                        }
                    }
                }
            }
        }
    }
    if (Strings.isNullOrBlank(clusterIP)) {
        // on vanilla kubernetes we can use nodePort to access things externally
        boolean found = false;
        Integer nodePort = port.getNodePort();
        if (nodePort != null) {
            try {
                NodeList nodeList = client.nodes().list();
                if (nodeList != null) {
                    List<Node> items = nodeList.getItems();
                    if (items != null) {
                        for (Node item : items) {
                            NodeStatus status = item.getStatus();
                            if (!found && status != null) {
                                List<NodeAddress> addresses = status.getAddresses();
                                if (addresses != null) {
                                    for (NodeAddress address : addresses) {
                                        String ip = address.getAddress();
                                        if (Strings.isNotBlank(ip)) {
                                            clusterIP = ip;
                                            portNumber = nodePort;
                                            found = true;
                                            break;
                                        }
                                    }
                                }
                            }
                            if (!found) {
                                NodeSpec spec = item.getSpec();
                                if (spec != null) {
                                    clusterIP = spec.getExternalID();
                                    if (Strings.isNotBlank(clusterIP)) {
                                        portNumber = nodePort;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                // ignore could not find a node!
                LOG.warn("Could not find a node!: " + e, e);
            }
        }
    }
    return (serviceProto + "://" + clusterIP + ":" + portNumber).toLowerCase();
}
Also used : JsonNode(com.fasterxml.jackson.databind.JsonNode) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) IngressList(io.fabric8.kubernetes.api.model.extensions.IngressList) HTTPIngressPath(io.fabric8.kubernetes.api.model.extensions.HTTPIngressPath) IngressSpec(io.fabric8.kubernetes.api.model.extensions.IngressSpec) IngressRule(io.fabric8.kubernetes.api.model.extensions.IngressRule) HTTPIngressRuleValue(io.fabric8.kubernetes.api.model.extensions.HTTPIngressRuleValue) Route(io.fabric8.openshift.api.model.Route) Ingress(io.fabric8.kubernetes.api.model.extensions.Ingress) SSLHandshakeException(javax.net.ssl.SSLHandshakeException) SSLException(javax.net.ssl.SSLException) TextParseException(org.xbill.DNS.TextParseException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) ParseException(java.text.ParseException) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException) SSLProtocolException(javax.net.ssl.SSLProtocolException) SSLKeyException(javax.net.ssl.SSLKeyException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) SSLPeerUnverifiedException(javax.net.ssl.SSLPeerUnverifiedException) DefaultOpenShiftClient(io.fabric8.openshift.client.DefaultOpenShiftClient) OpenShiftClient(io.fabric8.openshift.client.OpenShiftClient) IngressTLS(io.fabric8.kubernetes.api.model.extensions.IngressTLS) IngressBackend(io.fabric8.kubernetes.api.model.extensions.IngressBackend) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException)

Aggregations

ArrayList (java.util.ArrayList)11 HTTPIngressPath (io.fabric8.kubernetes.api.model.extensions.HTTPIngressPath)8 Ingress (io.fabric8.kubernetes.api.model.extensions.Ingress)8 HTTPIngressPathBuilder (io.fabric8.kubernetes.api.model.networking.v1.HTTPIngressPathBuilder)8 Ingress (io.fabric8.kubernetes.api.model.networking.v1.Ingress)8 IngressTLSBuilder (io.fabric8.kubernetes.api.model.networking.v1.IngressTLSBuilder)8 GenericKafkaListener (io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListener)8 IngressBackend (io.fabric8.kubernetes.api.model.extensions.IngressBackend)6 IngressTLS (io.fabric8.kubernetes.api.model.extensions.IngressTLS)5 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)4 HTTPIngressPathBuilder (io.fabric8.kubernetes.api.model.extensions.HTTPIngressPathBuilder)4 HTTPIngressRuleValue (io.fabric8.kubernetes.api.model.extensions.HTTPIngressRuleValue)4 IngressBuilder (io.fabric8.kubernetes.api.model.extensions.IngressBuilder)4 IngressRule (io.fabric8.kubernetes.api.model.extensions.IngressRule)4 IngressSpec (io.fabric8.kubernetes.api.model.extensions.IngressSpec)4 HTTPIngressPath (io.fabric8.kubernetes.api.model.networking.v1.HTTPIngressPath)4 IngressBuilder (io.fabric8.kubernetes.api.model.networking.v1.IngressBuilder)4 IngressRule (io.fabric8.kubernetes.api.model.networking.v1.IngressRule)4 IngressRuleBuilder (io.fabric8.kubernetes.api.model.networking.v1.IngressRuleBuilder)4 IngressTLS (io.fabric8.kubernetes.api.model.networking.v1.IngressTLS)4