Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cterasdk/edge/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
'shares',
'shell',
'smb',
'statistics',
'support',
'sync',
'syslog',
Expand Down
40 changes: 40 additions & 0 deletions cterasdk/edge/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,3 +437,43 @@ class ResourceError:
"""
FileExists = 'File exists'
Forbidden = 'Creating a folder in this location is forbidden'


class Metric:
"""
Metric

:ivar str CPU: CPU
:ivar str Memory: Memory
:ivar str Volume: Volume
:ivar str Cache: Cache Stats
:ivar str Connections: Connections
:ivar str Disk: Disk I/O
:ivar str Local: Local I/O
:ivar str CloudSync: Cloud Sync
"""
CPU = 'cpu'
Memory = 'memory'
Volume = 'volume'
Cache = 'cache'
Connections = 'connections'
Disk = 'disk_io'
Local = 'local_io'
CloudSync = 'cloud_io'


class Interval:
"""
Interval

:ivar str Hour: Hour (Real-time)
:ivar str Day: Day
:ivar str Week: Week
:ivar str Month: Month
:ivar str Year: Year
"""
Hour = 'hour'
Day = 'day'
Week = 'week'
Month = 'month'
Year = 'year'
2 changes: 1 addition & 1 deletion cterasdk/edge/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def remote_access(device, Portal):
logger.info("Enabling remote access. %s", {'tenant': device_tenant, 'device': device_name})
token = authn_token(Portal, device_tenant, device_name)
device_object = create_device_object(device)
device_object.sso(token)
device_object.sso(token, {Portal._session_id_key: Portal.get_session_id()}) # pylint: disable=protected-access
logger.info("Enabled remote access. %s", {'tenant': device_tenant, 'device': device_name})
return device_object

Expand Down
91 changes: 91 additions & 0 deletions cterasdk/edge/statistics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
from .enum import Metric
from .base_command import BaseCommand


class Statistics(BaseCommand):
""" Edge Filer Statistics API """

def cpu(self, interval):
"""
CPU Statistics

:param cterasdk.edge.enum.Interval interval: Interval
:return: Statistics Object
:rtype: cterasdk.common.object.Object
"""
return self._statistics(Metric.CPU, interval)

def memory(self, interval):
"""
Memory Statistics

:param cterasdk.edge.enum.Interval interval: Interval
:return: Statistics Object
:rtype: cterasdk.common.object.Object
"""
return self._statistics(Metric.Memory, interval)

def volume(self, interval):
"""
Volume Statistics

:param cterasdk.edge.enum.Interval interval: Interval
:return: Statistics Object
:rtype: cterasdk.common.object.Object
"""
return self._statistics(Metric.Volume, interval)

def cache(self, interval):
"""
Cache Statistics

:param cterasdk.edge.enum.Interval interval: Interval
:return: Statistics Object
:rtype: cterasdk.common.object.Object
"""
return self._statistics(Metric.Cache, interval)

def connections(self, interval):
"""
Connections Statistics

:param cterasdk.edge.enum.Interval interval: Interval
:return: Statistics Object
:rtype: cterasdk.common.object.Object
"""
return self._statistics(Metric.Connections, interval)

def disk(self, interval):
"""
Disk I/O Statistics

:param cterasdk.edge.enum.Interval interval: Interval
:return: Statistics Object
:rtype: cterasdk.common.object.Object
"""
return self._statistics(Metric.Disk, interval)

def local_io(self, interval):
"""
Local I/O Statistics

:param cterasdk.edge.enum.Interval interval: Interval
:return: Statistics Object
:rtype: cterasdk.common.object.Object
"""
return self._statistics(Metric.Local, interval)

def cloudsync(self, interval):
"""
Cloud Synchronization Statistics

:param cterasdk.edge.enum.Interval interval: Interval
:return: Statistics Object
:rtype: cterasdk.common.object.Object
"""
return self._statistics(Metric.CloudSync, interval)

def _statistics(self, metric, interval):
return self._edge.clients.stats.get(metric, params={
'interval': interval
})
4 changes: 2 additions & 2 deletions cterasdk/objects/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,13 @@ def test(self):
def _session_id_key(self):
return NotImplementedError("Subclass must implement the '_session_id_key' property")

def get_session_id(self):
def get_session_id(self, response_url=None):
"""
Get Session Identifier

:return str: Session ID
"""
return self._default.cookie_jar.get(self._default.baseurl, self._session_id_key)
return self._default.cookie_jar.get(response_url if response_url else self._default.baseurl, self._session_id_key)

def set_session_id(self, session_id):
self._default.cookie_jar.update_cookies({self._session_id_key: session_id}, self._default.baseurl)
Expand Down
3 changes: 3 additions & 0 deletions cterasdk/objects/synchronous/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ def context(self):
def _session_id_key(self):
return 'JSESSIONID'

def get_session_id(self): # pylint: disable=arguments-differ
return super().get_session_id(self.ctera.baseurl)

def _authenticator(self, url):
return authenticators.core(self.session(), url, self.context)

Expand Down
18 changes: 13 additions & 5 deletions cterasdk/objects/synchronous/edge.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
afp, aio, antivirus, array, audit, backup, cache, cli, config, connection, ctera_migrate,
dedup, directoryservice, drive, files, firmware, ftp, groups, licenses, login,
logs, mail, network, nfs, ntp, power, remote, rsync, ransom_protect, services,
shares, shell, smb, snmp, ssh, ssl, support, sync, syslog, tasks, telnet,
shares, shell, smb, snmp, ssh, ssl, statistics, support, sync, syslog, tasks, telnet,
timezone, users, volumes,
)

Expand All @@ -27,6 +27,7 @@ def __init__(self, edge, Portal):
else:
self.migrate = edge.default.clone(clients.Migrate, EndpointBuilder.new(edge.base, '/migration/rest/v1'))
self.api = edge.default.clone(clients.API, EndpointBuilder.new(edge.base, '/admingui/api'))
self.stats = edge.default.clone(clients.JSON, EndpointBuilder.new(edge.base, '/stats'))
self.io = IO(edge)


Expand Down Expand Up @@ -108,6 +109,7 @@ def __init__(self, host=None, port=None, https=True, Portal=None, *, base=None):
self.snmp = snmp.SNMP(self)
self.ssh = ssh.SSH(self)
self.ssl = modules.initialize(ssl.SSLModule, self)
self.statistics = statistics.Statistics(self)
self.support = support.Support(self)
self.sync = sync.Sync(self)
self.syslog = syslog.Syslog(self)
Expand Down Expand Up @@ -151,8 +153,14 @@ def initialized(self):
def test(self):
return connection.test(self)

def sso(self, ticket):
""" Login using Single Sign On"""
def sso(self, ticket, session):
"""
Single Sign on from CTERA Portal to CTERA Edge Filer.

:param str ticket: SSO Ticket
:param dict session: CTERA Portal Session Cookie
"""
self.default.cookie_jar.update_cookies(session, self.default.baseurl)
self._login_object.sso(ticket)
self.session().start_session(self)

Expand All @@ -164,5 +172,5 @@ def _omit_fields(self):
return super()._omit_fields + ['afp', 'aio', 'array', 'audit', 'antivirus', 'backup', 'cache', 'cli', 'config', 'ctera_migrate',
'dedup', 'directoryservice', 'drive', 'files', 'firmware', 'ftp', 'groups', 'licenses', 'logs',
'mail', 'network', 'nfs', 'ntp', 'power', 'ransom_protect', 'rsync', 'services', 'shares', 'shell',
'smb', 'snmp', 'ssh', 'ssl', 'support', 'sync', 'syslog', 'tasks', 'telnet', 'timezone',
'users', 'volumes']
'smb', 'snmp', 'ssh', 'ssl', 'statistics', 'support', 'sync', 'syslog', 'tasks', 'telnet',
'timezone', 'users', 'volumes']
59 changes: 59 additions & 0 deletions docs/source/UserGuides/Edge/Configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,65 @@ SSH

edge.ssh.disable()

Statistics
==========

.. automethod:: cterasdk.edge.statistics.Statistics.cpu
:noindex:

.. code-block:: python

edge.statistics.cpu(edge_enum.Interval.Day)

.. automethod:: cterasdk.edge.statistics.Statistics.memory
:noindex:

.. code-block:: python

edge.statistics.memory(edge_enum.Interval.Day)

.. automethod:: cterasdk.edge.statistics.Statistics.volume
:noindex:

.. code-block:: python

edge.statistics.volume(edge_enum.Interval.Day)

.. automethod:: cterasdk.edge.statistics.Statistics.cache
:noindex:

.. code-block:: python

edge.statistics.cache(edge_enum.Interval.Day)

.. automethod:: cterasdk.edge.statistics.Statistics.connections
:noindex:

.. code-block:: python

edge.statistics.connections(edge_enum.Interval.Day)

.. automethod:: cterasdk.edge.statistics.Statistics.disk
:noindex:

.. code-block:: python

edge.statistics.disk(edge_enum.Interval.Day)

.. automethod:: cterasdk.edge.statistics.Statistics.local_io
:noindex:

.. code-block:: python

edge.statistics.local_io(edge_enum.Interval.Day)

.. automethod:: cterasdk.edge.statistics.Statistics.cloudsync
:noindex:

.. code-block:: python

edge.statistics.cloudsync(edge_enum.Interval.Day)

Miscellaneous
-------------

Expand Down
62 changes: 62 additions & 0 deletions tests/ut/edge/test_statistics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from unittest import mock

from cterasdk.edge import statistics
from cterasdk.edge.enum import Interval, Metric
from tests.ut.edge import base_edge


class TestEdgeStatistics(base_edge.BaseEdgeTest):

def setUp(self):
super().setUp()
self._filer.clients.stats.get = mock.MagicMock()
self.intervals = (Interval.Hour, Interval.Day, Interval.Week, Interval.Month, Interval.Year)

def test_cpu(self):
for interval in self.intervals:
self._init_filer()
statistics.Statistics(self._filer).cpu(interval)
self._filer.clients.stats.get.assert_called_with(Metric.CPU, params={'interval': interval})

def test_memory(self):
self._init_filer()
for interval in self.intervals:
self._init_filer()
statistics.Statistics(self._filer).memory(interval)
self._filer.clients.stats.get.assert_called_with(Metric.Memory, params={'interval': interval})

def test_volume(self):
for interval in self.intervals:
self._init_filer()
statistics.Statistics(self._filer).volume(interval)
self._filer.clients.stats.get.assert_called_with(Metric.Volume, params={'interval': interval})

def test_cache(self):
for interval in self.intervals:
self._init_filer()
statistics.Statistics(self._filer).cache(interval)
self._filer.clients.stats.get.assert_called_with(Metric.Cache, params={'interval': interval})

def test_connections(self):
for interval in self.intervals:
self._init_filer()
statistics.Statistics(self._filer).connections(interval)
self._filer.clients.stats.get.assert_called_with(Metric.Connections, params={'interval': interval})

def test_disk(self):
for interval in self.intervals:
self._init_filer()
statistics.Statistics(self._filer).disk(interval)
self._filer.clients.stats.get.assert_called_with(Metric.Disk, params={'interval': interval})

def test_local_io(self):
for interval in self.intervals:
self._init_filer()
statistics.Statistics(self._filer).local_io(interval)
self._filer.clients.stats.get.assert_called_with(Metric.Local, params={'interval': interval})

def test_cloudsync(self):
for interval in self.intervals:
self._init_filer()
statistics.Statistics(self._filer).cloudsync(interval)
self._filer.clients.stats.get.assert_called_with(Metric.CloudSync, params={'interval': interval})
Loading