Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
bitonio committed Feb 2, 2022
2 parents 6e4e694 + 62f37e2 commit fcbbcfd
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 16 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ You will get 7 extra columns:
- Idle dialout connections
- Active dialout connections

To correlate with application served by each connectors, use the `--showapps`, a list of the application FQDNs as an array in the JSON response.

#### Swapping connectors

If you are doing a maintenance on an hypervizor, you may need to swap out 2 connectors.
Expand Down Expand Up @@ -261,7 +263,7 @@ Use 'akamai eaa cert crt://certificate-UUID status' to monitor the progress.
Checking the status of the deployment:

```
./akamai-eaa cert crt://certificate-UUID status
$ akamai eaa cert crt://certificate-UUID status
#App/IdP ID,name,status
app://appid-1,Multi-origin Active-Active Demo (US-East),Pending
app://appid-2,Multi-origin Active-Active Demo (US-West),Pending
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.4.5
0.4.6
3 changes: 2 additions & 1 deletion bin/akamai-eaa
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,10 @@ if __name__ == "__main__":
# Unless the long form "akamai eaa connector list" is used
# the ArgumentParser won't have the attribute set
json = hasattr(config, 'json') and config.json
show_apps = hasattr(config, 'showapps') and config.showapps
tail = hasattr(config, 'tail') and config.tail
interval = hasattr(config, 'interval') and config.interval
c.list(perf, json, tail, interval, cli.stop_event)
c.list(perf, json, show_apps, tail, interval, cli.stop_event)
elif config.command in ("certificate", "cert"):
c = CertificateAPI(config)
if config.action is None or config.action == "list" or config.certificate_id is None:
Expand Down
2 changes: 2 additions & 0 deletions bin/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ def __init__(self, config_values, configuration, flags=None):
list_parser = subsub.add_parser("list", help="List all connectors")
list_parser.add_argument('--perf', default=False, action="store_true", help='Show performance metrics')
list_parser.add_argument('--json', '-j', default=False, action="store_true", help='View as JSON')
list_parser.add_argument('--showapps', '-a', default=False, action="store_true",
help='Response contains the applications running on the connector (JSON only)')
list_parser.add_argument('--tail', '-f', default=False, action="store_true", help='Keep watching, do not exit until Control+C/SIGTERM')
list_parser.add_argument('--interval', '-i', default=300, type=float, help='Interval between update (works with --tail only)')
# subparsers.required = False
Expand Down
2 changes: 1 addition & 1 deletion cli.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"commands": [
{
"name": "eaa",
"version": "0.4.5",
"version": "0.4.6",
"description": "Akamai CLI for Enterprise Application Access (EAA)"
}
]
Expand Down
2 changes: 1 addition & 1 deletion libeaa/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
config = EdgeGridConfig({'verbose': False}, 'default')

#: cli-eaa version
__version__ = '0.4.5'
__version__ = '0.4.6'

#: HTTP Request Timeout in seconds
HTTP_REQ_TIMEOUT = 300
Expand Down
55 changes: 44 additions & 11 deletions libeaa/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import time
import json
import signal
from functools import lru_cache


from common import cli, BaseAPI, EAAItem
from application import ApplicationAPI
Expand All @@ -28,6 +30,7 @@ class ConnectorAPI(BaseAPI):
"""
POOL_SIZE = 6 # When doing sub request, max concurrency of underlying HTTP request
LIMIT_SOFT = 256 # Soft limit of maximum of connectors to retreive at once
APP_CACHE_TTL = 300 # How long we consider the app <-> connector mapping accurate enough
NODATA = "-" # Output value in the CSV cell if data is not available
NODATA_JSON = None # Output value in the CSV cell if data is not available

Expand Down Expand Up @@ -96,7 +99,7 @@ def perf_apps(self, connector_id):
perf_by_host[perf_by_app.get('app_name')] = perf_by_app.get('histogram_data')[-1]
return perf_by_host

def list_once(self, perf=False, json_fmt=False):
def list_once(self, perf=False, json_fmt=False, show_apps=False):
"""
Display the list of EAA connectors as comma separated CSV or JSON
TODO: refactor this method, too long
Expand All @@ -110,8 +113,7 @@ def list_once(self, perf=False, json_fmt=False):
if perf:
header += ",last_upd,CPU%,Mem%,Disk%,NetworkMbps,do_total,do_idle,do_active"
format_line += ",{ts},{cpu},{mem},{disk},{network},{dialout_total},{dialout_idle},{dialout_active}"

if perf: # Add performance metrics in the report
# Add performance metrics in the report
perf_res_list = None
signal.signal(signal.SIGTERM, signal.SIG_DFL)
with Pool(ConnectorAPI.POOL_SIZE) as p:
Expand Down Expand Up @@ -151,6 +153,12 @@ def list_once(self, perf=False, json_fmt=False):
"dialout_idle": perf_latest.get('dialout_idle') or ConnectorAPI.NODATA_JSON,
"dialout_active": perf_latest.get('active_dialout_count') or ConnectorAPI.NODATA_JSON
})
# Help SIEM with the mapping connector <-> apps
if show_apps:
apps = []
for a in self.findappbyconnector(EAAItem("con://" + c.get('uuid_url'))):
apps.append(str(a[2]))
data.update({"apps": apps})
if not json_fmt:
cli.print(format_line.format(
scheme=EAAItem.Type.Connector.scheme,
Expand All @@ -176,14 +184,15 @@ def list_once(self, perf=False, json_fmt=False):
if not json_fmt:
cli.footer("Total %s connector(s)" % total_con)

def list(self, perf, json_fmt, follow=False, interval=300, stop_event=None):
def list(self, perf, json_fmt, show_apps=False, follow=False, interval=300, stop_event=None):
"""
List the connector and their attributes and status
The default output is CSV
Args:
perf (bool): Add performance data (cpu, mem, disk, dialout)
json_fmt (bool): Output as JSON instead of CSV
show_apps (bool): Add an extra field 'apps' as array of application UUID
follow (bool): Never stop until Control+C or SIGTERM is received
interval (float): Interval in seconds between pulling the API, default is 5 minutes (300s)
stop_event (Event): Main program stop event allowing the function
Expand All @@ -192,7 +201,7 @@ def list(self, perf, json_fmt, follow=False, interval=300, stop_event=None):
while True or (stop_event and not stop_event.is_set()):
try:
start = time.time()
self.list_once(perf, json_fmt)
self.list_once(perf, json_fmt, show_apps)
if follow:
sleep_time = interval - (time.time() - start)

Expand All @@ -213,6 +222,24 @@ def list(self, perf, json_fmt, follow=False, interval=300, stop_event=None):
else:
raise

@lru_cache(maxsize=1)
def all_apps(self, exp):
"""
This method is expensive in time so we use `lru_cache decorator`
with a size of 1, combined with a functiom argument `exp` that will be
used as expiration or cache key.
Args:
exp (integer): cache key
Returns:
[dict]: JSON dictionnary containing all the applications for this tenant
"""
url_params = {'limit': ApplicationAPI.LIMIT_SOFT, 'expand': 'true'}
search_app = self.get('mgmt-pop/apps', params=url_params)
print(search_app.json())
return search_app.json()


def findappbyconnector(self, connector_moniker):
"""
Find EAA Applications using a particular connector.
Expand All @@ -221,31 +248,37 @@ def findappbyconnector(self, connector_moniker):
connector_moniker (EAAItem): Connector ID.
Returns:
Tuple of 3 values:
Tuple of 4 values:
- application moniker
- application name
- application host (external hostname)
- application host (external hostname - FQDN)
- dialout version (1 or 2)
Raises:
TypeError: If the argument is wrong type.
"""

if not isinstance(connector_moniker, EAAItem):
raise TypeError("EAAItem expected.")
url_params = {'limit': ApplicationAPI.LIMIT_SOFT, 'expand': 'true'}
search_app = self.get('mgmt-pop/apps', params=url_params)
apps = search_app.json()

now = time.time()
exp = now - now % (-1 * ConnectorAPI.APP_CACHE_TTL)
apps = self.all_apps(exp)

logging.debug("Searching app using %s..." % connector_moniker)
for app in apps.get('objects', []):
# Only tunnel apps are using Dialout Version 2
dialout_ver = 2 if app.get('app_profile') == ApplicationAPI.Profile.TCP.value else 1
for con in app.get('agents', []):
app_moniker = EAAItem("app://" + app.get('uuid_url'))
con_moniker = EAAItem("con://" + con.get('uuid_url'))
app_host = app.get('host')
if app.get('domain') == 2:
app_host += "." + app.get('domain_suffix')
if con_moniker == connector_moniker:
yield app_moniker, \
app.get('name'), \
app.get('host'), \
app_host, \
dialout_ver

def list_apps(self, con_moniker, perf=False):
Expand Down

0 comments on commit fcbbcfd

Please sign in to comment.