Skip to content
This repository has been archived by the owner on Oct 3, 2020. It is now read-only.

Commit

Permalink
Ingress application (#80)
Browse files Browse the repository at this point in the history
* find application via ingress backend/service

* doc string
  • Loading branch information
hjacobs authored May 12, 2019
1 parent d599642 commit daaca7f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
3 changes: 2 additions & 1 deletion deploy/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ metadata:
name: kube-resource-report
rules:
- apiGroups: [""]
resources: ["nodes", "pods", "namespaces"]
resources: ["nodes", "pods", "namespaces", "services"]
verbs:
- get
- list
- apiGroups: ["extensions"]
resources: ["ingresses"]
Expand Down
41 changes: 39 additions & 2 deletions kube_resource_report/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from jinja2 import Environment, FileSystemLoader, select_autoescape

import pykube
from pykube import Namespace, Pod, Node, Ingress
from pykube import Namespace, Pod, Node, Ingress, Service, ObjectDoesNotExist
from pykube.objects import APIObject, NamespacedAPIObject

from kube_resource_report import cluster_discovery, pricing, filters, __version__
Expand Down Expand Up @@ -161,6 +161,38 @@ def get_pod_usage(cluster, pods: dict):
logger.exception("Failed to get pod usage metrics")


def find_backend_application(client, ingress, rule):
'''
The Ingress object might not have a "application" label, so let's try to find the application by looking at the backend service and its pods
'''
paths = rule.get('http', {}).get('paths', [])
selectors = []
for path in paths:
service_name = path.get('backend', {}).get('serviceName')
if service_name:
try:
service = Service.objects(client, namespace=ingress.namespace).get(name=service_name)
except ObjectDoesNotExist:
logger.debug(f'Referenced service does not exist: {ingress.namespace}/{service_name}')
else:
selector = service.obj['spec'].get('selector', {})
selectors.append(selector)
application = get_application_from_labels(selector)
if application:
return application
# we still haven't found the application, let's look up pods by label selectors
for selector in selectors:
application_candidates = set()
for pod in Pod.objects(client).filter(namespace=ingress.namespace, selector=selector):
application = get_application_from_labels(pod.labels)
if application:
application_candidates.add(application)

if len(application_candidates) == 1:
return application_candidates.pop()
return ''


def query_cluster(
cluster, executor, system_namespaces, additional_cost_per_cluster, no_ingress_status, node_label
):
Expand Down Expand Up @@ -308,7 +340,12 @@ def query_cluster(
application = get_application_from_labels(_ingress.labels)
for rule in _ingress.obj["spec"].get("rules", []):
host = rule.get('host', '')
ingress = [_ingress.namespace, _ingress.name, application, host, 0]
if not application:
# find the application by getting labels from pods
backend_application = find_backend_application(cluster.client, _ingress, rule)
else:
backend_application = None
ingress = [_ingress.namespace, _ingress.name, application or backend_application, host, 0]
if host and not no_ingress_status:
try:
future = futures_by_host[host]
Expand Down

0 comments on commit daaca7f

Please sign in to comment.