185 lines
4.3 KiB
Python
185 lines
4.3 KiB
Python
"""
|
|
.. 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
|
|
:license: Apache, see LICENSE for more details.
|
|
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
|
|
|
|
"""
|
|
import arrow
|
|
|
|
from sqlalchemy import func
|
|
|
|
from lemur import database
|
|
from lemur.common.utils import truthiness
|
|
from lemur.endpoints.models import Endpoint, Policy, Cipher
|
|
from lemur.extensions import metrics
|
|
|
|
|
|
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):
|
|
"""
|
|
Retrieves an endpoint given it's name.
|
|
|
|
:param name:
|
|
:return:
|
|
"""
|
|
return database.get(Endpoint, name, field="name")
|
|
|
|
|
|
def get_by_dnsname(dnsname):
|
|
"""
|
|
Retrieves an endpoint given it's name.
|
|
|
|
:param dnsname:
|
|
:return:
|
|
"""
|
|
return database.get(Endpoint, dnsname, field="dnsname")
|
|
|
|
|
|
def get_by_dnsname_and_port(dnsname, port):
|
|
"""
|
|
Retrieves and endpoint by it's dnsname and port.
|
|
:param dnsname:
|
|
:param port:
|
|
:return:
|
|
"""
|
|
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()
|
|
|
|
|
|
def create(**kwargs):
|
|
"""
|
|
Creates a new endpoint.
|
|
:param kwargs:
|
|
:return:
|
|
"""
|
|
endpoint = Endpoint(**kwargs)
|
|
database.create(endpoint)
|
|
metrics.send(
|
|
"endpoint_added", "counter", 1, metric_tags={"source": endpoint.source.label}
|
|
)
|
|
return endpoint
|
|
|
|
|
|
def get_or_create_policy(**kwargs):
|
|
policy = database.get(Policy, kwargs["name"], field="name")
|
|
|
|
if not policy:
|
|
policy = Policy(**kwargs)
|
|
database.create(policy)
|
|
|
|
return policy
|
|
|
|
|
|
def get_or_create_cipher(**kwargs):
|
|
cipher = database.get(Cipher, kwargs["name"], field="name")
|
|
|
|
if not cipher:
|
|
cipher = Cipher(**kwargs)
|
|
database.create(cipher)
|
|
|
|
return cipher
|
|
|
|
|
|
def update(endpoint_id, **kwargs):
|
|
endpoint = database.get(Endpoint, endpoint_id)
|
|
|
|
endpoint.policy = kwargs["policy"]
|
|
endpoint.certificate = kwargs["certificate"]
|
|
endpoint.source = kwargs["source"]
|
|
endpoint.last_updated = arrow.utcnow()
|
|
metrics.send(
|
|
"endpoint_updated", "counter", 1, metric_tags={"source": endpoint.source.label}
|
|
)
|
|
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)
|
|
filt = args.pop("filter")
|
|
|
|
if filt:
|
|
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]))
|
|
elif "port" in filt:
|
|
if terms[1] != "null": # ng-table adds 'null' if a number is removed
|
|
query = query.filter(Endpoint.port == terms[1])
|
|
elif "ciphers" in filt:
|
|
query = query.filter(Cipher.name == terms[1])
|
|
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:
|
|
"""
|
|
attr = getattr(Endpoint, kwargs.get("metric"))
|
|
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)
|
|
|
|
return {"labels": keys, "values": values}
|