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

Commit

Permalink
v0.4.7
Browse files Browse the repository at this point in the history
  • Loading branch information
gabstopper committed Mar 9, 2017
1 parent dfa4e43 commit ae98946
Show file tree
Hide file tree
Showing 23 changed files with 142 additions and 176 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Python 3.4, 3.5 (version >- 0.4)

Requests

Security Management Center version 5.10, 6.0, 6.1, 6.1.1
Security Management Center version 5.10, 6.0, 6.1, 6.1.1, 6.1.2

##### Getting Started

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ def readme():
return f.read()

setup(name='smc-python',
version='0.4.6',
version='0.4.7',
description='Python based API to Stonesoft Security Management Center',
url='http://github.com/gabstopper/smc-python',
author='David LePage',
Expand Down
3 changes: 3 additions & 0 deletions smc/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,6 @@ Simplified read/write access to interface details
All SMCResult actions are wrapped in exceptions
Global metaclass registry

$version 0.4.7
move template, inspection policy to base policy
element.from_href had etag, cache set backwards
2 changes: 1 addition & 1 deletion smc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from smc.api.session import Session

__author__ = 'David LePage'
__version__ = '0.4.6'
__version__ = '0.4.7'

# Default SMC Session
session = Session()
Expand Down
4 changes: 2 additions & 2 deletions smc/administration/access_rights.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
on the SMC and optionally applied to elements such as engines.
"""

from smc.base.model import Element, ElementFactory
from smc.base.model import Element

class AccessControlList(Element):
"""
Expand Down Expand Up @@ -31,7 +31,7 @@ def granted_element(self):
:return: Element class deriving from :py:class:`smc.base.model.Element`
"""
return [ElementFactory(e) for e in self._granted_element]
return [Element.from_href(e) for e in self._granted_element]

@property
def comment(self):
Expand Down
9 changes: 7 additions & 2 deletions smc/administration/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,12 @@ def abort(self):
"""
prepared_request(ActionCommandFailed,
href=find_link_by_name('abort', self.link)).delete()


def __call__(self):
_task = search.element_by_href_as_json(self.follower)
for k, v in _task.items():
setattr(self, k, v)

def __getattr__(self, value):
"""
Last Message attribute may not be available initially, so
Expand Down Expand Up @@ -173,7 +178,6 @@ def task_handler(task, wait_for_finish=False,
#first task will not have a last_message attribute
last_msg = ''
while True:
task = Task(**search.element_by_href_as_json(task.follower))
if display_msg:
if task.last_message != last_msg and \
task.last_message is not None:
Expand All @@ -186,5 +190,6 @@ def task_handler(task, wait_for_finish=False,
elif not task.in_progress and not task.success:
break
time.sleep(sleep)
task()
else:
yield task.follower
5 changes: 0 additions & 5 deletions smc/api/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from smc.api.exceptions import SMCOperationFailure, SMCConnectionError,\
UnsupportedEntryPoint
from smc.base.util import unicode_to_bytes
from smc.api.counter import countcalls

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -87,22 +86,18 @@ def __init__(self, href=None, json=None, params=None, filename=None,
setattr(self, k, v)

@method('POST')
@countcalls
def create(self):
return self._make_request()

@method('DELETE')
@countcalls
def delete(self):
return self._make_request()

@method('PUT')
@countcalls
def update(self):
return self._make_request()

@method('GET')
@countcalls
def read(self):
return self._make_request()

Expand Down
22 changes: 0 additions & 22 deletions smc/api/counter.py

This file was deleted.

9 changes: 3 additions & 6 deletions smc/api/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
import json
import logging
import requests
import smc.api.counter
from smc.api.web import SMCAPIConnection
import smc.api.web
from smc.api.exceptions import SMCConnectionError, ConfigLoadError,\
UnsupportedEntryPoint
from smc.api.configloader import load_from_file
Expand Down Expand Up @@ -129,7 +128,7 @@ def login(self, url=None, api_key=None, api_version=None,
self._session.verify = verify #make verify setting persistent
logger.debug("Login succeeded and session retrieved: %s", \
self.session_id)
self._connection = SMCAPIConnection(self)
self._connection = smc.api.web.SMCAPIConnection(self)
else:
raise SMCConnectionError("Login failed, HTTP status code: %s" \
% r.status_code)
Expand All @@ -140,9 +139,7 @@ def logout(self):
r = self.session.put(self.cache.get_entry_href('logout'))
if r.status_code == 204:
logger.info("Logged out successfully")
c = smc.api.common.countcalls.counts()
c.update({'cache': smc.api.counter.cache_hit})
logger.debug("Query counters: %s" % c)
logger.debug("Call counters: %s" % smc.api.web.counters)
else:
logger.error("Logout status was unexpected. Received response "
"was status code: %s", (r.status_code))
Expand Down
24 changes: 18 additions & 6 deletions smc/api/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
https://urllib3.readthedocs.io/en/latest/user-guide.html#ssl
"""
import os.path
import collections
import requests
import logging
import smc.api.counter # @UnusedImport
from smc.api.exceptions import SMCOperationFailure, SMCConnectionError

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -54,11 +54,11 @@ def send_request(self, method, request):
response.encoding = 'utf-8'

logger.debug(vars(response))
counters.update(read=1)

if response.status_code not in (200, 304):
raise SMCOperationFailure(response)
if response.status_code == 304:
smc.api.counter.cache_hit += 1



elif method == SMCAPIConnection.POST:
if request.files: #File upload request
Expand All @@ -72,6 +72,8 @@ def send_request(self, method, request):
response.encoding = 'utf-8'

logger.debug(vars(response))
counters.update(create=1)

if response.status_code not in (200, 201, 202):
# 202 is asynchronous response with follower link
raise SMCOperationFailure(response)
Expand All @@ -86,14 +88,18 @@ def send_request(self, method, request):
params=request.params,
headers=request.headers)

logger.debug(vars(response))
logger.debug(vars(response))
counters.update(update=1)

if response.status_code != 200:
raise SMCOperationFailure(response)

elif method == SMCAPIConnection.DELETE:
response = self.session.delete(request.href)
response.encoding = 'utf-8'

counters.update(delete=1)

if response.status_code not in (200, 204):
raise SMCOperationFailure(response)

Expand Down Expand Up @@ -136,7 +142,7 @@ def file_download(self, request):
handle.flush()
except IOError as e:
raise IOError('Error attempting to save to file: {}'.format(e))
#return SMCResult(msg=e)

result = SMCResult(response)
result.content = path
return result
Expand Down Expand Up @@ -214,3 +220,9 @@ def __str__(self):
for key in self.__dict__:
sb.append("{key}='{value}'".format(key=key, value=self.__dict__[key]))
return ', '.join(sb)

counters = collections.Counter({'read': 0,
'create': 0,
'update': 0,
'delete': 0,
'cache': 0})
26 changes: 14 additions & 12 deletions smc/base/model.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Class representing basic models for data obtained or retrieved from the SMC
Classes representing basic models for data obtained or retrieved from the SMC
ElementBase is the top level parent class that provides the instance level
cache, meta data and basic methods operate on retrieved data.
Expand Down Expand Up @@ -103,10 +103,9 @@ def ElementFactory(href):
e = typeof(name=element.json.get('name'),
meta=Meta(href=href,
type=istype))
e._cache = Cache(e, element.etag, element.json)
e._cache = Cache(e, element.json, element.etag)
return e

cachehit = 0
class Cache(object):
"""
Cache can be applied at the element level to provide an
Expand Down Expand Up @@ -135,24 +134,27 @@ def __call__(self, *args, **kwargs):
if result.code != 304:
result.json.update(self._cache[1])
self._cache = (result.etag, result.json)
else:
global cachehit
cachehit += 1
return self._cache

class ElementLocator(object):
"""
There are two ways to get an elements location, either through the
describe_xxx methods which is then stored in the instance meta attribute,
or by specifying the resource directly, i.e. Host('myhost').
describe_xxx methods which returns the instance type with the populated
meta attribute, or by loading the resource directly, i.e. Host('myhost').
If the element is loaded directly, it must have a class attribute
If the element is loaded directly, it should define a class attribute
'typeof' to specify the element type. The 'typeof' attribute correlates
to the SMC API entry point for the element. Classes deriving from
:class:`Element` will inherit this descriptor.
:class:`Element` will define this attribute. When loading via Host('myhost'),
you will have an empty instance as the cache is not hydrated until some action
is called on it that accesses the instance property 'data'.
Once hydrated, original json is stored in instance._cache.
Classes deriving from :class:`SubElement` do not have valid entry points in
the SMC API and will be typically created through a reference link.
SubElements do not have valid entry points in the SMC API and will be
created through a reference and will derive from :class:`SubElement`.
This descriptor is a non data descriptor and can be overridden if 'href'
is defined in the instance dict.
"""
def __get__(self, instance, cls=None):
#Does the instance already have meta data
Expand Down
4 changes: 0 additions & 4 deletions smc/base/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,5 @@ class Registry(type):
def __new__(meta, name, bases, clsdict): # @NoSelf
cls = super(Registry, meta).__new__(meta, name, bases, clsdict)
if 'typeof' in clsdict:
#if isinstance(clsdict['typeof'], list):
# for attr in clsdict['typeof']:
# meta._registry[attr] = cls
#else:
meta._registry[clsdict['typeof']] = cls
return cls
4 changes: 2 additions & 2 deletions smc/base/util.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Utility functions used in different areas of smc-python
"""
from ..compat import PY3
import smc.compat as compat
import smc.api.exceptions

def save_to_file(filename, content):
Expand Down Expand Up @@ -71,7 +71,7 @@ def bytes_to_unicode(s, encoding='utf-8', errors='replace'):
:param str errors: what to do when decoding fails
:return: unicode utf-8 string
"""
if PY3:
if compat.PY3:
return str(s,'utf-8') if isinstance(s, bytes) else s
else:
return s if isinstance(s, unicode) else s.decode(encoding, errors) # @UndefinedVariable
14 changes: 6 additions & 8 deletions smc/core/route.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,9 @@ def all(self):
return [node for node in iter(self)]

def __str__(self):
return '{0}(name={1},level={2})'.format(
self.__class__.__name__,
self.name,
self.level)
return '{0}(name={1},level={2})'.format(self.__class__.__name__,
self.name,
self.level)
def __repr__(self):
return str(self)

Expand Down Expand Up @@ -267,10 +266,9 @@ def all(self):
return [node for node in iter(self)]

def __str__(self):
return '{0}(name={1},level={2})'.format(
self.__class__.__name__,
self.name,
self.level)
return '{0}(name={1},level={2})'.format(self.__class__.__name__,
self.name,
self.level)
def __repr__(self):
return str(self)

11 changes: 4 additions & 7 deletions smc/docs/pages/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
Reference
*********

Element
-------
Element is the top level class for most elements represented in the SMC. Element
contains many methods that allow a common interface as well as helpers to simplify
finding elements.
Base
----

.. automodule:: smc.base.model
:members: Element
:members: ElementBase, Element, SubElement

Elements
--------
Expand Down Expand Up @@ -493,7 +490,7 @@ IPSPolicy
InspectionPolicy
++++++++++++++++

.. automodule:: smc.policy.inspection
.. autoclass:: smc.policy.policy.InspectionPolicy
:members:
:show-inheritance:

Expand Down
Loading

0 comments on commit ae98946

Please sign in to comment.