lemur/lemur/endpoints/service.py

185 lines
4.3 KiB
Python
Raw Normal View History

2016-06-27 23:40:46 +02:00
"""
.. module: lemur.endpoints.service
:platform: Unix
:synopsis: This module contains all of the services level functions used to
administer endpoints in Lemur
:copyright: (c) 2018 by Netflix Inc., see AUTHORS for more
2016-06-27 23:40:46 +02:00
:license: Apache, see LICENSE for more details.
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
"""
2016-12-15 19:26:59 +01:00
import arrow
from sqlalchemy import func
2016-06-27 23:40:46 +02:00
from lemur import database
from lemur.common.utils import truthiness
2016-06-27 23:40:46 +02:00
from lemur.endpoints.models import Endpoint, Policy, Cipher
from lemur.extensions import metrics
2016-06-27 23:40:46 +02:00
def get_all():
"""
Get all endpoints that are currently in Lemur.
:rtype : List
:return:
"""
query = database.session_query(Endpoint)
return database.find_all(query, Endpoint, {}).all()
def get(endpoint_id):
"""
Retrieves an endpoint given it's ID
:param endpoint_id:
:return:
"""
return database.get(Endpoint, endpoint_id)
def get_by_name(name):
2016-06-27 23:40:46 +02:00
"""
Retrieves an endpoint given it's name.
:param name:
2016-06-27 23:40:46 +02:00
:return:
"""
2019-05-16 16:57:02 +02:00
return database.get(Endpoint, name, field="name")
def get_by_dnsname(dnsname):
"""
Retrieves an endpoint given it's name.
:param dnsname:
:return:
"""
2019-05-16 16:57:02 +02:00
return database.get(Endpoint, dnsname, field="dnsname")
2016-06-27 23:40:46 +02:00
def get_by_dnsname_and_port(dnsname, port):
"""
Retrieves and endpoint by it's dnsname and port.
:param dnsname:
:param port:
:return:
"""
2019-05-16 16:57:02 +02:00
return (
Endpoint.query.filter(Endpoint.dnsname == dnsname)
.filter(Endpoint.port == port)
.scalar()
)
def get_by_source(source_label):
"""
Retrieves all endpoints for a given source.
:param source_label:
:return:
"""
return Endpoint.query.filter(Endpoint.source.label == source_label).all() # noqa
def get_all_pending_rotation():
"""
Retrieves all endpoints which have certificates deployed
that have been replaced.
:return:
"""
return Endpoint.query.filter(Endpoint.replaced.any()).all()
2016-06-27 23:40:46 +02:00
def create(**kwargs):
"""
Creates a new endpoint.
:param kwargs:
:return:
"""
endpoint = Endpoint(**kwargs)
database.create(endpoint)
2019-05-16 16:57:02 +02:00
metrics.send(
"endpoint_added", "counter", 1, metric_tags={"source": endpoint.source.label}
)
2016-06-27 23:40:46 +02:00
return endpoint
def get_or_create_policy(**kwargs):
2019-05-16 16:57:02 +02:00
policy = database.get(Policy, kwargs["name"], field="name")
2016-06-27 23:40:46 +02:00
if not policy:
policy = Policy(**kwargs)
database.create(policy)
return policy
def get_or_create_cipher(**kwargs):
2019-05-16 16:57:02 +02:00
cipher = database.get(Cipher, kwargs["name"], field="name")
2016-06-27 23:40:46 +02:00
if not cipher:
cipher = Cipher(**kwargs)
database.create(cipher)
return cipher
def update(endpoint_id, **kwargs):
endpoint = database.get(Endpoint, endpoint_id)
2019-05-16 16:57:02 +02:00
endpoint.policy = kwargs["policy"]
endpoint.certificate = kwargs["certificate"]
endpoint.source = kwargs["source"]
2016-12-15 19:26:59 +01:00
endpoint.last_updated = arrow.utcnow()
2019-05-16 16:57:02 +02:00
metrics.send(
"endpoint_updated", "counter", 1, metric_tags={"source": endpoint.source.label}
)
2016-06-27 23:40:46 +02:00
database.update(endpoint)
return endpoint
def render(args):
"""
Helper that helps us render the REST Api responses.
:param args:
:return:
"""
query = database.session_query(Endpoint)
2019-05-16 16:57:02 +02:00
filt = args.pop("filter")
2016-06-27 23:40:46 +02:00
if filt:
2019-05-16 16:57:02 +02:00
terms = filt.split(";")
if "active" in filt: # this is really weird but strcmp seems to not work here??
query = query.filter(Endpoint.active == truthiness(terms[1]))
2019-05-16 16:57:02 +02:00
elif "port" in filt:
if terms[1] != "null": # ng-table adds 'null' if a number is removed
2016-06-27 23:40:46 +02:00
query = query.filter(Endpoint.port == terms[1])
2019-05-16 16:57:02 +02:00
elif "ciphers" in filt:
query = query.filter(Cipher.name == terms[1])
2016-06-27 23:40:46 +02:00
else:
query = database.filter(query, Endpoint, terms)
return database.sort_and_page(query, Endpoint, args)
def stats(**kwargs):
"""
Helper that defines some useful statistics about endpoints.
:param kwargs:
:return:
"""
2019-05-16 16:57:02 +02:00
attr = getattr(Endpoint, kwargs.get("metric"))
2016-06-27 23:40:46 +02:00
query = database.db.session.query(attr, func.count(attr))
items = query.group_by(attr).all()
keys = []
values = []
for key, count in items:
keys.append(key)
values.append(count)
2019-05-16 16:57:02 +02:00
return {"labels": keys, "values": values}