forked from shaba/openuds
fixing up sample service
This commit is contained in:
parent
76a17b19df
commit
d48e71cfd3
@ -64,49 +64,50 @@ class Transports(ModelHandler):
|
||||
return transports.factory().providers().values()
|
||||
|
||||
def getGui(self, type_: str) -> typing.List[typing.Any]:
|
||||
try:
|
||||
field = self.addDefaultFields(transports.actory().lookup(type_).guiDescription(), ['name', 'comments', 'tags', 'priority'])
|
||||
field = self.addField(field, {
|
||||
'name': 'nets_positive',
|
||||
'value': True,
|
||||
'label': ugettext('Network access'),
|
||||
'tooltip': ugettext('If checked, the transport will be enabled for the selected networks. If unchecked, transport will be disabled for selected networks'),
|
||||
'type': 'checkbox',
|
||||
'order': 100, # At end
|
||||
})
|
||||
field = self.addField(field, {
|
||||
'name': 'networks',
|
||||
'value': [],
|
||||
'values': sorted([{'id': x.id, 'text': x.name} for x in Network.objects.all()], key=lambda x: x['text'].lower()),
|
||||
'label': ugettext('Networks'),
|
||||
'tooltip': ugettext('Networks associated with this transport. If No network selected, will mean "all networks"'),
|
||||
'type': 'multichoice',
|
||||
'order': 101
|
||||
})
|
||||
field = self.addField(field, {
|
||||
'name': 'allowed_oss',
|
||||
'value': [],
|
||||
'values': sorted([{'id': x, 'text': x} for x in OsDetector.knownOss], key=lambda x: x['text'].lower()),
|
||||
'label': ugettext('Allowed Devices'),
|
||||
'tooltip': ugettext('If empty, any kind of device compatible with this transport will be allowed. Else, only devices compatible with selected values will be allowed'),
|
||||
'type': 'multichoice',
|
||||
'order': 102
|
||||
})
|
||||
field = self.addField(field, {
|
||||
'name': 'pools',
|
||||
'value': [],
|
||||
'values': [{'id': x.id, 'text': x.name} for x in ServicePool.objects.all().order_by('name')],
|
||||
'label': ugettext('Service Pools'),
|
||||
'tooltip': ugettext('Currently assigned services pools'),
|
||||
'type': 'multichoice',
|
||||
'order': 103
|
||||
})
|
||||
transport = transports.factory().lookup(type_)
|
||||
|
||||
return field
|
||||
|
||||
except Exception:
|
||||
if not transport:
|
||||
raise self.invalidItemException()
|
||||
|
||||
field = self.addDefaultFields(transport.guiDescription(), ['name', 'comments', 'tags', 'priority'])
|
||||
field = self.addField(field, {
|
||||
'name': 'nets_positive',
|
||||
'value': True,
|
||||
'label': ugettext('Network access'),
|
||||
'tooltip': ugettext('If checked, the transport will be enabled for the selected networks. If unchecked, transport will be disabled for selected networks'),
|
||||
'type': 'checkbox',
|
||||
'order': 100, # At end
|
||||
})
|
||||
field = self.addField(field, {
|
||||
'name': 'networks',
|
||||
'value': [],
|
||||
'values': sorted([{'id': x.id, 'text': x.name} for x in Network.objects.all()], key=lambda x: x['text'].lower()),
|
||||
'label': ugettext('Networks'),
|
||||
'tooltip': ugettext('Networks associated with this transport. If No network selected, will mean "all networks"'),
|
||||
'type': 'multichoice',
|
||||
'order': 101
|
||||
})
|
||||
field = self.addField(field, {
|
||||
'name': 'allowed_oss',
|
||||
'value': [],
|
||||
'values': sorted([{'id': x, 'text': x} for x in OsDetector.knownOss], key=lambda x: x['text'].lower()),
|
||||
'label': ugettext('Allowed Devices'),
|
||||
'tooltip': ugettext('If empty, any kind of device compatible with this transport will be allowed. Else, only devices compatible with selected values will be allowed'),
|
||||
'type': 'multichoice',
|
||||
'order': 102
|
||||
})
|
||||
field = self.addField(field, {
|
||||
'name': 'pools',
|
||||
'value': [],
|
||||
'values': [{'id': x.id, 'text': x.name} for x in ServicePool.objects.all().order_by('name')],
|
||||
'label': ugettext('Service Pools'),
|
||||
'tooltip': ugettext('Currently assigned services pools'),
|
||||
'type': 'multichoice',
|
||||
'order': 103
|
||||
})
|
||||
|
||||
return field
|
||||
|
||||
def item_as_dict(self, item: Transport) -> typing.Dict[str, typing.Any]:
|
||||
type_ = item.getType()
|
||||
return {
|
||||
|
@ -34,11 +34,12 @@ UDS Service modules interfaces and classes.
|
||||
"""
|
||||
from .transport import Transport
|
||||
from .transport import DIRECT_GROUP, TUNNELED_GROUP
|
||||
from .transport_factory import TransportsFactory
|
||||
from . import protocols
|
||||
|
||||
def factory():
|
||||
|
||||
def factory() -> TransportsFactory:
|
||||
"""
|
||||
Returns factory for register/access to service providers
|
||||
"""
|
||||
from .transport_factory import TransportsFactory
|
||||
return TransportsFactory.factory()
|
||||
|
@ -40,5 +40,4 @@ For this, we must simply import the class at __init__, UDS will take care
|
||||
of the rest
|
||||
"""
|
||||
|
||||
from .SampleProvider import Provider
|
||||
|
||||
from .provider import Provider
|
||||
|
@ -30,15 +30,22 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
|
||||
from uds.core.services import UserDeployment
|
||||
from uds.core.util.state import State
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from uds.core import services
|
||||
from uds.core.util.state import State
|
||||
|
||||
# Not imported at runtime, just for type checking
|
||||
if typing.TYPE_CHECKING:
|
||||
from uds import models
|
||||
from .service import ServiceOne
|
||||
from .publication import SamplePublication
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SampleUserDeploymentOne(UserDeployment):
|
||||
class SampleUserDeploymentOne(services.UserDeployment):
|
||||
"""
|
||||
This class generates the user consumable elements of the service tree.
|
||||
|
||||
@ -72,17 +79,16 @@ class SampleUserDeploymentOne(UserDeployment):
|
||||
suggestedTime = 5
|
||||
|
||||
# Serializable needed methods
|
||||
def marshal(self):
|
||||
def marshal(self) -> bytes:
|
||||
"""
|
||||
Does nothing right here, we will use environment storage in this sample
|
||||
"""
|
||||
return b''
|
||||
|
||||
def unmarshal(self, str_):
|
||||
def unmarshal(self, data: bytes) -> None:
|
||||
"""
|
||||
Does nothing here also, all data are kept at environment storage
|
||||
"""
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
"""
|
@ -30,16 +30,23 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
|
||||
from uds.core.services import UserDeployment
|
||||
from uds.core.util.state import State
|
||||
import logging
|
||||
import codecs
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from uds.core import services
|
||||
from uds.core.util.state import State
|
||||
|
||||
# Not imported at runtime, just for type checking
|
||||
if typing.TYPE_CHECKING:
|
||||
from uds import models
|
||||
from .service import ServiceOne
|
||||
from .publication import SamplePublication
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SampleUserDeploymentTwo(UserDeployment):
|
||||
class SampleUserDeploymentTwo(services.UserDeployment):
|
||||
"""
|
||||
This class generates the user consumable elements of the service tree.
|
||||
|
@ -32,18 +32,24 @@ Created on Jun 22, 2012
|
||||
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
import logging
|
||||
import typing
|
||||
|
||||
|
||||
from django.utils.translation import ugettext_noop as _
|
||||
from uds.core.services import ServiceProvider
|
||||
from .SampleService import ServiceOne, ServiceTwo
|
||||
from uds.core import services
|
||||
from uds.core.ui import gui
|
||||
from .service import ServiceOne, ServiceTwo
|
||||
|
||||
import logging
|
||||
# Not imported at runtime, just for type checking
|
||||
if typing.TYPE_CHECKING:
|
||||
from uds.core import Module
|
||||
from uds.core.environment import Environment
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Provider(ServiceProvider):
|
||||
class Provider(services.ServiceProvider):
|
||||
"""
|
||||
This class represents the sample services provider
|
||||
|
||||
@ -87,14 +93,16 @@ class Provider(ServiceProvider):
|
||||
|
||||
# : Remote host. Here core will translate label and tooltip, remember to
|
||||
# : mark them as _ using ugettext_noop.
|
||||
remoteHost = gui.TextField(oder=1,
|
||||
remoteHost = gui.TextField(
|
||||
oder=1,
|
||||
length=64,
|
||||
label=_('Remote host'),
|
||||
tooltip=_('This fields contains a remote host'),
|
||||
required=True,
|
||||
)
|
||||
# : Name of your pet (sample, not really needed :-) )
|
||||
petName = gui.TextField(order=2,
|
||||
petName = gui.TextField(
|
||||
order=2,
|
||||
length=32,
|
||||
label=_('Your pet\'s name'),
|
||||
tooltip=_('If you like, write the name of your pet'),
|
||||
@ -104,7 +112,8 @@ class Provider(ServiceProvider):
|
||||
# : Age of Methuselah (matusalén in spanish)
|
||||
# : in Spain there is a well-known to say that something is very old,
|
||||
# : "Tiene mas años que matusalén"(is older than Methuselah)
|
||||
methAge = gui.NumericField(order=3,
|
||||
methAge = gui.NumericField(
|
||||
order=3,
|
||||
length=4, # That is, max allowed value is 9999
|
||||
label=_('Age of Methuselah'),
|
||||
tooltip=_('If you know it, please, tell me!!!'),
|
||||
@ -113,14 +122,16 @@ class Provider(ServiceProvider):
|
||||
)
|
||||
|
||||
# : Is Methuselah istill alive?
|
||||
methAlive = gui.CheckBoxField(order=4,
|
||||
methAlive = gui.CheckBoxField(
|
||||
order=4,
|
||||
label=_('Is Methuselah still alive?'),
|
||||
tooltip=_('If you fail, this will not get saved :-)'),
|
||||
required=True, # : Also means nothing. Check boxes has always a value
|
||||
defvalue=gui.TRUE # : By default, at new item, check this
|
||||
)
|
||||
|
||||
methText = gui.TextField(order=5,
|
||||
methText = gui.TextField(
|
||||
order=5,
|
||||
length=512,
|
||||
multiline=5,
|
||||
label=_('Text area'),
|
||||
@ -130,7 +141,7 @@ class Provider(ServiceProvider):
|
||||
)
|
||||
|
||||
# There is more fields type, but not here the best place to cover it
|
||||
def initialize(self, values=None):
|
||||
def initialize(self, values: 'Module.ValuesType') -> None:
|
||||
"""
|
||||
We will use the "autosave" feature for form fields, that is more than
|
||||
enought for most providers. (We simply need to store data provided by user
|
||||
@ -143,8 +154,8 @@ class Provider(ServiceProvider):
|
||||
# If you say meth is alive, you are wrong!!! (i guess..)
|
||||
# values are only passed from administration client. Internals
|
||||
# instantiations are always empty.
|
||||
if values is not None and self.methAlive.isTrue():
|
||||
raise ServiceProvider.ValidationException(_('Methuselah is not alive!!! :-)'))
|
||||
if values and self.methAlive.isTrue():
|
||||
raise services.ServiceProvider.ValidationException(_('Methuselah is not alive!!! :-)'))
|
||||
|
||||
# Marshal and unmarshal are defaults ones, also enought
|
||||
|
||||
@ -152,7 +163,7 @@ class Provider(ServiceProvider):
|
||||
# base class so we don't have to mess with all those things...
|
||||
|
||||
@staticmethod
|
||||
def test(env, data):
|
||||
def test(env: 'Environment', data: typing.Dict[str, str]) -> typing.List[typing.Any]:
|
||||
"""
|
||||
Create your test method here so the admin can push the "check" button
|
||||
and this gets executed.
|
||||
@ -176,9 +187,8 @@ class Provider(ServiceProvider):
|
||||
try:
|
||||
# We instantiate the provider, but this may fail...
|
||||
instance = Provider(env, data)
|
||||
logger.debug('Methuselah has {0} years and is {1} :-)'
|
||||
.format(instance.methAge.value, instance.methAlive.value))
|
||||
except ServiceProvider.ValidationException as e:
|
||||
logger.debug('Methuselah has %s years and is %s :-)', instance.methAge.value, instance.methAlive.value)
|
||||
except services.ServiceProvider.ValidationException as e:
|
||||
# If we say that meth is alive, instantiation will
|
||||
return [False, str(e)]
|
||||
except Exception as e:
|
||||
@ -191,15 +201,15 @@ class Provider(ServiceProvider):
|
||||
#
|
||||
# From now onwards, we implement our own methods, that will be used by,
|
||||
# for example, services derived from this provider
|
||||
def host(self):
|
||||
def host(self) -> str:
|
||||
"""
|
||||
Sample method, in fact in this we just return
|
||||
the value of host field, that is an string
|
||||
"""
|
||||
return self.remoteHost.value
|
||||
|
||||
def methYears(self):
|
||||
def methYears(self) -> int:
|
||||
"""
|
||||
Another sample return, it will in fact return the Methuselah years
|
||||
"""
|
||||
return self.methAge.value()
|
||||
return self.methAge.num()
|
@ -30,15 +30,19 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
from uds.core.services import Publication
|
||||
from uds.core.util.state import State
|
||||
from datetime import datetime
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Not imported at runtime, just for type checking
|
||||
if typing.TYPE_CHECKING:
|
||||
from .service import ServiceOne, ServiceTwo
|
||||
|
||||
|
||||
class SamplePublication(Publication):
|
||||
"""
|
||||
@ -79,6 +83,9 @@ class SamplePublication(Publication):
|
||||
"""
|
||||
|
||||
suggestedTime = 5 # : Suggested recheck time if publication is unfinished in seconds
|
||||
_name: str = ''
|
||||
_reason: str = ''
|
||||
_number: int = -1
|
||||
|
||||
def initialize(self):
|
||||
"""
|
||||
@ -104,9 +111,9 @@ class SamplePublication(Publication):
|
||||
"""
|
||||
deserializes the data and loads it inside instance.
|
||||
"""
|
||||
logger.debug('Data: {0}'.format(data))
|
||||
logger.debug('Data: %s', data)
|
||||
vals = data.decode('utf8').split('\t')
|
||||
logger.debug('Values: {0}'.format(vals))
|
||||
logger.debug('Values: %s', vals)
|
||||
self._name = vals[0]
|
||||
self._reason = vals[1]
|
||||
self._number = int(vals[2])
|
@ -30,20 +30,26 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from django.utils.translation import ugettext_noop as _
|
||||
from uds.core.services import Service
|
||||
from .SamplePublication import SamplePublication
|
||||
from .SampleUserDeploymentOne import SampleUserDeploymentOne
|
||||
from .SampleUserDeploymentTwo import SampleUserDeploymentTwo
|
||||
|
||||
from uds.core import services
|
||||
from uds.core.ui import gui
|
||||
|
||||
import logging
|
||||
from .publication import SamplePublication
|
||||
from .deployment_one import SampleUserDeploymentOne
|
||||
from .deployment_two import SampleUserDeploymentTwo
|
||||
|
||||
|
||||
# Not imported at runtime, just for type checking
|
||||
if typing.TYPE_CHECKING:
|
||||
from uds.core import Module
|
||||
from uds.core.environment import Environment
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ServiceOne(Service):
|
||||
class ServiceOne(services.Service):
|
||||
"""
|
||||
Basic service, the first part (variables) include the description of the service.
|
||||
|
||||
@ -114,33 +120,37 @@ class ServiceOne(Service):
|
||||
# If we don't indicate an order, the output order of fields will be
|
||||
# "random"
|
||||
|
||||
colour = gui.ChoiceField(order=1,
|
||||
label=_('Colour'),
|
||||
tooltip=_('Colour of the field'),
|
||||
# In this case, the choice can have none value selected by default
|
||||
required=True,
|
||||
values=[ gui.choiceItem('red', 'Red'),
|
||||
gui.choiceItem('green', 'Green'),
|
||||
gui.choiceItem('blue', 'Blue'),
|
||||
gui.choiceItem('nonsense', 'Blagenta')
|
||||
],
|
||||
defvalue='1' # Default value is the ID of the choicefield
|
||||
)
|
||||
colour = gui.ChoiceField(
|
||||
order=1,
|
||||
label=_('Colour'),
|
||||
tooltip=_('Colour of the field'),
|
||||
# In this case, the choice can have none value selected by default
|
||||
required=True,
|
||||
values=[
|
||||
gui.choiceItem('red', 'Red'),
|
||||
gui.choiceItem('green', 'Green'),
|
||||
gui.choiceItem('blue', 'Blue'),
|
||||
gui.choiceItem('nonsense', 'Blagenta')
|
||||
],
|
||||
defvalue='1' # Default value is the ID of the choicefield
|
||||
)
|
||||
|
||||
passw = gui.PasswordField(order=2,
|
||||
label=_('Password'),
|
||||
tooltip=_('Password for testing purposes'),
|
||||
required=True,
|
||||
defvalue='1234' # : Default password are nonsense?? :-)
|
||||
)
|
||||
passw = gui.PasswordField(
|
||||
order=2,
|
||||
label=_('Password'),
|
||||
tooltip=_('Password for testing purposes'),
|
||||
required=True,
|
||||
defvalue='1234' # : Default password are nonsense?? :-)
|
||||
)
|
||||
|
||||
baseName = gui.TextField(order=3,
|
||||
label=_('Services names'),
|
||||
tooltip=_('Base name for this user services'),
|
||||
# In this case, the choice can have none value selected by default
|
||||
required=True,
|
||||
defvalue='' # Default value is the ID of the choicefield
|
||||
)
|
||||
baseName = gui.TextField(
|
||||
order=3,
|
||||
label=_('Services names'),
|
||||
tooltip=_('Base name for this user services'),
|
||||
# In this case, the choice can have none value selected by default
|
||||
required=True,
|
||||
defvalue='' # Default value is the ID of the choicefield
|
||||
)
|
||||
|
||||
def initialize(self, values):
|
||||
"""
|
||||
@ -155,7 +165,7 @@ class ServiceOne(Service):
|
||||
# so we only need to validate params if values is not None
|
||||
if values is not None:
|
||||
if self.colour.value == 'nonsense':
|
||||
raise Service.ValidationException('The selected colour is invalid!!!')
|
||||
raise services.Service.ValidationException('The selected colour is invalid!!!')
|
||||
|
||||
|
||||
# Services itself are non testeable right now, so we don't even have
|
||||
@ -189,7 +199,7 @@ class ServiceOne(Service):
|
||||
|
||||
|
||||
|
||||
class ServiceTwo(Service):
|
||||
class ServiceTwo(services.Service):
|
||||
"""
|
||||
Just a second service, no comments here (almost same that ServiceOne
|
||||
"""
|
Loading…
Reference in New Issue
Block a user