mirror of
https://github.com/dkmstr/openuds.git
synced 2024-12-22 13:34:04 +03:00
Renamed some fields of servers to better understand what they are
Adding physical machines fixtures, tests, ,,,
This commit is contained in:
parent
30bbf1ef0f
commit
6694b9d5bc
@ -78,9 +78,9 @@ class ActorTokens(ModelHandler):
|
||||
log_level = LogLevel(log_level_int).name
|
||||
return {
|
||||
'id': item.token,
|
||||
'name': str(_('Token isued by {} from {}')).format(item.username, item.hostname or item.ip),
|
||||
'name': str(_('Token isued by {} from {}')).format(item.register_username, item.hostname or item.ip),
|
||||
'stamp': item.stamp,
|
||||
'username': item.username,
|
||||
'username': item.register_username,
|
||||
'ip': item.ip,
|
||||
'host': f'{item.ip} - {data.get("mac")}',
|
||||
'hostname': item.hostname,
|
||||
|
@ -282,8 +282,8 @@ class Register(ActorV3Action):
|
||||
# This means that we can invoke its API from user_service, but not from server (The actor token is transformed as soon as initialized to a user service token)
|
||||
if actor_token:
|
||||
# Update parameters
|
||||
actor_token.username = self._user.pretty_name
|
||||
actor_token.ip_from = self._request.ip
|
||||
actor_token.register_username = self._user.pretty_name
|
||||
actor_token.register_ip = self._request.ip
|
||||
actor_token.ip = self._params['ip']
|
||||
actor_token.hostname = self._params['hostname']
|
||||
actor_token.log_level = self._params['log_level']
|
||||
@ -301,8 +301,8 @@ class Register(ActorV3Action):
|
||||
|
||||
if not found:
|
||||
kwargs = {
|
||||
'username': self._user.pretty_name,
|
||||
'ip_from': self._request.ip,
|
||||
'register_username': self._user.pretty_name,
|
||||
'register_ip': self._request.ip,
|
||||
'ip': self._params['ip'],
|
||||
'hostname': self._params['hostname'],
|
||||
'log_level': self._params['log_level'],
|
||||
|
@ -101,10 +101,10 @@ class ServerRegisterBase(Handler):
|
||||
serverToken = serverTokens[0]
|
||||
# Update parameters
|
||||
# serverToken.hostname = self._params['hostname']
|
||||
serverToken.username = self._user.pretty_name
|
||||
serverToken.register_username = self._user.pretty_name
|
||||
serverToken.certificate = certificate
|
||||
# Ensure we do not store zone if IPv6 and present
|
||||
serverToken.ip_from = self._request.ip.split('%')[0]
|
||||
serverToken.register_ip = self._request.ip.split('%')[0]
|
||||
serverToken.listen_port = port
|
||||
serverToken.ip = ip
|
||||
serverToken.stamp = now
|
||||
@ -116,8 +116,8 @@ class ServerRegisterBase(Handler):
|
||||
except Exception:
|
||||
try:
|
||||
serverToken = models.Server.objects.create(
|
||||
username=self._user.pretty_name,
|
||||
ip_from=self._request.ip.split('%')[0], # Ensure we do not store zone if IPv6 and present
|
||||
register_username=self._user.pretty_name,
|
||||
register_ip=self._request.ip.split('%')[0], # Ensure we do not store zone if IPv6 and present
|
||||
ip=ip,
|
||||
listen_port=port,
|
||||
hostname=self._params['hostname'],
|
||||
|
@ -75,9 +75,9 @@ class ServersTokens(ModelHandler):
|
||||
item = typing.cast('models.Server', item) # We will receive for sure
|
||||
return {
|
||||
'id': item.uuid,
|
||||
'name': str(_('Token isued by {} from {}')).format(item.username, item.ip),
|
||||
'name': str(_('Token isued by {} from {}')).format(item.register_username, item.ip),
|
||||
'stamp': item.stamp,
|
||||
'username': item.username,
|
||||
'username': item.register_username,
|
||||
'ip': item.ip,
|
||||
'hostname': item.hostname,
|
||||
'listen_port': item.listen_port,
|
||||
@ -257,7 +257,8 @@ class ServersServers(DetailHandler):
|
||||
raise self.invalid_request_response('Invalid MAC address')
|
||||
# Create a new one, and add it to group
|
||||
server = models.Server.objects.create(
|
||||
ip_from='::1',
|
||||
register_username=self._user.name,
|
||||
register_ip=self._request.ip,
|
||||
ip=self._params['ip'],
|
||||
hostname=self._params['hostname'],
|
||||
listen_port=0,
|
||||
@ -288,6 +289,9 @@ class ServersServers(DetailHandler):
|
||||
raise self.invalid_request_response('Invalid MAC address')
|
||||
try:
|
||||
models.Server.objects.filter(uuid=process_uuid(item)).update(
|
||||
# Update register info also on update
|
||||
register_username=self._user.name,
|
||||
register_ip=self._request.ip,
|
||||
ip=self._params['ip'],
|
||||
hostname=self._params['hostname'],
|
||||
mac=mac,
|
||||
|
@ -203,7 +203,7 @@ class ServerManager(metaclass=singleton.Singleton):
|
||||
service_type: Type of service to assign
|
||||
min_memory_mb: Minimum memory required for server in MB, does not apply to unmanaged servers
|
||||
lock_interval: If not None, lock server for this time
|
||||
server: If not None, use this server instead of selecting one from serverGroup. (Used on manual assign)
|
||||
server: If not None, use this server instead of selecting one from server_group. (Used on manual assign)
|
||||
excluded_servers_uuids: If not None, exclude this servers from selection. Used in case we check the availability of a server
|
||||
with some external method and we want to exclude it from selection because it has already failed.
|
||||
|
||||
@ -280,24 +280,24 @@ class ServerManager(metaclass=singleton.Singleton):
|
||||
# Update counter
|
||||
info = types.servers.ServerCounter(info.server_uuid, info.counter + 1)
|
||||
props[prop_name] = info
|
||||
bestServer = models.Server.objects.get(uuid=info.server_uuid)
|
||||
best_server = models.Server.objects.get(uuid=info.server_uuid)
|
||||
|
||||
# Ensure next assignation will have updated stats
|
||||
# This is a simple simulation on cached stats, will be updated on next stats retrieval
|
||||
# (currently, cache time is 1 minute)
|
||||
bestServer.interpolate_new_assignation()
|
||||
best_server.interpolate_new_assignation()
|
||||
|
||||
# Notify assgination in every case, even if reassignation to same server is made
|
||||
# This lets the server to keep track, if needed, of multi-assignations
|
||||
self.notify_assign(bestServer, userservice, service_type, info.counter)
|
||||
self.notify_assign(best_server, userservice, service_type, info.counter)
|
||||
return info
|
||||
|
||||
def release(
|
||||
self,
|
||||
userService: 'models.UserService',
|
||||
serverGroup: 'models.ServerGroup',
|
||||
userservice: 'models.UserService',
|
||||
server_group: 'models.ServerGroup',
|
||||
unlock: bool = False,
|
||||
userUuid: typing.Optional[str] = None,
|
||||
user_uuid: typing.Optional[str] = None,
|
||||
) -> types.servers.ServerCounter:
|
||||
"""
|
||||
Unassigns a server from an user
|
||||
@ -308,13 +308,13 @@ class ServerManager(metaclass=singleton.Singleton):
|
||||
unlock: If True, unlock server, even if it has more users assigned to it
|
||||
userUuid: If not None, use this uuid instead of userService.user.uuid
|
||||
"""
|
||||
userUuid = userUuid if userUuid else userService.user.uuid if userService.user else None
|
||||
user_uuid = user_uuid if user_uuid else userservice.user.uuid if userservice.user else None
|
||||
|
||||
if userUuid is None:
|
||||
if user_uuid is None:
|
||||
return types.servers.ServerCounter.null() # No user is assigned to this service, nothing to do
|
||||
|
||||
prop_name = self.property_name(userService.user)
|
||||
with serverGroup.properties as props:
|
||||
prop_name = self.property_name(userservice.user)
|
||||
with server_group.properties as props:
|
||||
with transaction.atomic():
|
||||
resetCounter = False
|
||||
# ServerCounterType
|
||||
@ -353,39 +353,39 @@ class ServerManager(metaclass=singleton.Singleton):
|
||||
# (currently, cache time is 1 minute)
|
||||
server.interpolate_new_release()
|
||||
|
||||
self.notify_release(server, userService)
|
||||
self.notify_release(server, userservice)
|
||||
|
||||
return types.servers.ServerCounter(serverCounter.server_uuid, serverCounter.counter - 1)
|
||||
|
||||
def notify_preconnect(
|
||||
self,
|
||||
serverGroup: 'models.ServerGroup',
|
||||
userService: 'models.UserService',
|
||||
server_group: 'models.ServerGroup',
|
||||
userservice: 'models.UserService',
|
||||
info: types.connections.ConnectionData,
|
||||
server: typing.Optional[
|
||||
'models.Server'
|
||||
] = None, # Forced server instead of selecting one from serverGroup
|
||||
] = None, # Forced server instead of selecting one from server_group
|
||||
) -> None:
|
||||
"""
|
||||
Notifies preconnect to server
|
||||
"""
|
||||
if not server:
|
||||
server = self.server_assignation_for(userService, serverGroup)
|
||||
server = self.server_assignation_for(userservice, server_group)
|
||||
|
||||
if server:
|
||||
requester.ServerApiRequester(server).notify_preconnect(userService, info)
|
||||
requester.ServerApiRequester(server).notify_preconnect(userservice, info)
|
||||
|
||||
def notify_assign(
|
||||
self,
|
||||
server: 'models.Server',
|
||||
userService: 'models.UserService',
|
||||
serviceType: types.services.ServiceType,
|
||||
userservice: 'models.UserService',
|
||||
service_type: types.services.ServiceType,
|
||||
counter: int,
|
||||
) -> None:
|
||||
"""
|
||||
Notifies assign to server
|
||||
"""
|
||||
requester.ServerApiRequester(server).notify_assign(userService, serviceType, counter)
|
||||
requester.ServerApiRequester(server).notify_assign(userservice, service_type, counter)
|
||||
|
||||
def notify_release(
|
||||
self,
|
||||
@ -397,19 +397,19 @@ class ServerManager(metaclass=singleton.Singleton):
|
||||
"""
|
||||
requester.ServerApiRequester(server).notify_release(userService)
|
||||
|
||||
def assignation_info(self, serverGroup: 'models.ServerGroup') -> dict[str, int]:
|
||||
def assignation_info(self, server_group: 'models.ServerGroup') -> dict[str, int]:
|
||||
"""
|
||||
Get usage information for a server group
|
||||
|
||||
Args:
|
||||
serverGroup: Server group to get current usage from
|
||||
server_group: Server group to get current usage from
|
||||
|
||||
Returns:
|
||||
Dict of current usage (user uuid, counter for assignations to that user)
|
||||
|
||||
"""
|
||||
res: dict[str, int] = {}
|
||||
for k, v in serverGroup.properties.items():
|
||||
for k, v in server_group.properties.items():
|
||||
if k.startswith(self.BASE_PROPERTY_NAME):
|
||||
kk = k[len(self.BASE_PROPERTY_NAME) :] # Skip base name
|
||||
res[kk] = res.get(kk, 0) + v[1]
|
||||
@ -417,24 +417,24 @@ class ServerManager(metaclass=singleton.Singleton):
|
||||
|
||||
def server_assignation_for(
|
||||
self,
|
||||
userService: 'models.UserService',
|
||||
serverGroup: 'models.ServerGroup',
|
||||
userservice: 'models.UserService',
|
||||
server_group: 'models.ServerGroup',
|
||||
) -> typing.Optional['models.Server']:
|
||||
"""
|
||||
Returns the server assigned to an user service
|
||||
|
||||
Args:
|
||||
userService: User service to get server from
|
||||
serverGroup: Server group to get server from
|
||||
server_group: Server group to get server from
|
||||
|
||||
Returns:
|
||||
Server assigned to user service, or None if no server is assigned
|
||||
"""
|
||||
if not userService.user:
|
||||
if not userservice.user:
|
||||
raise exceptions.UDSException(_('No user assigned to service'))
|
||||
|
||||
prop_name = self.property_name(userService.user)
|
||||
with serverGroup.properties as props:
|
||||
prop_name = self.property_name(userservice.user)
|
||||
with server_group.properties as props:
|
||||
info: typing.Optional[types.servers.ServerCounter] = types.servers.ServerCounter.from_iterable(
|
||||
props.get(prop_name)
|
||||
)
|
||||
@ -444,21 +444,21 @@ class ServerManager(metaclass=singleton.Singleton):
|
||||
|
||||
def sorted_server_list(
|
||||
self,
|
||||
serverGroup: 'models.ServerGroup',
|
||||
server_group: 'models.ServerGroup',
|
||||
excluded_servers_uuids: typing.Optional[typing.Set[str]] = None,
|
||||
) -> list['models.Server']:
|
||||
"""
|
||||
Returns a list of servers sorted by usage
|
||||
|
||||
Args:
|
||||
serverGroup: Server group to get servers from
|
||||
server_group: Server group to get servers from
|
||||
|
||||
Returns:
|
||||
List of servers sorted by usage
|
||||
"""
|
||||
with transaction.atomic():
|
||||
now = model_utils.sql_datetime()
|
||||
fltrs = serverGroup.servers.filter(maintenance_mode=False)
|
||||
fltrs = server_group.servers.filter(maintenance_mode=False)
|
||||
fltrs = fltrs.filter(Q(locked_until=None) | Q(locked_until__lte=now)) # Only unlocked servers
|
||||
if excluded_servers_uuids:
|
||||
fltrs = fltrs.exclude(uuid__in=excluded_servers_uuids)
|
||||
@ -468,23 +468,23 @@ class ServerManager(metaclass=singleton.Singleton):
|
||||
# Sort by weight, lower first (lower is better)
|
||||
return [s[1] for s in sorted(serverStats, key=lambda x: x[0].weight() if x[0] else 999999999)]
|
||||
|
||||
def perform_maintenance(self, serverGroup: 'models.ServerGroup') -> None:
|
||||
def perform_maintenance(self, server_group: 'models.ServerGroup') -> None:
|
||||
"""Realizes maintenance on server group
|
||||
|
||||
Maintenace operations include:
|
||||
* Clean up removed users from server counters
|
||||
|
||||
Args:
|
||||
serverGroup: Server group to realize maintenance on
|
||||
server_group: Server group to realize maintenance on
|
||||
"""
|
||||
for k, _ in serverGroup.properties.items():
|
||||
for k, _ in server_group.properties.items():
|
||||
if k.startswith(self.BASE_PROPERTY_NAME):
|
||||
uuid = k[len(self.BASE_PROPERTY_NAME) :]
|
||||
try:
|
||||
models.User.objects.get(uuid=uuid)
|
||||
except Exception:
|
||||
# User does not exists, remove it from counters
|
||||
del serverGroup.properties[k]
|
||||
del server_group.properties[k]
|
||||
|
||||
def process_event(self, server: 'models.Server', data: dict[str, typing.Any]) -> typing.Any:
|
||||
"""
|
||||
|
@ -120,7 +120,6 @@ def server_group_field(
|
||||
_server_group_values, valid_types, subtype
|
||||
), # So it gets evaluated at runtime
|
||||
tab=tab,
|
||||
old_field_name='serverGroup',
|
||||
)
|
||||
|
||||
|
||||
|
@ -33,8 +33,8 @@ def migrate_old_data(apps: typing.Any, schema_editor: typing.Any) -> None:
|
||||
# Now append actors to registered servers, with "unknown" os type (legacy)
|
||||
for token in ActorToken.objects.all():
|
||||
Server.objects.create(
|
||||
username=token.username,
|
||||
ip_from=token.ip_from,
|
||||
register_username=token.username,
|
||||
register_ip=token.ip_from,
|
||||
ip=token.ip,
|
||||
hostname=token.hostname,
|
||||
token=token.token,
|
||||
@ -69,8 +69,8 @@ def rollback_old_data(apps: typing.Any, schema_editor: typing.Any) -> None:
|
||||
if not server.data:
|
||||
continue # Skip servers without data, they are not actors!!
|
||||
ActorToken.objects.create(
|
||||
username=server.username,
|
||||
ip_from=server.ip_from,
|
||||
username=server.register_username,
|
||||
ip_from=server.register_ip,
|
||||
ip=server.ip,
|
||||
hostname=server.hostname,
|
||||
token=server.token,
|
||||
@ -127,6 +127,16 @@ class Migration(migrations.Migration):
|
||||
'TunnelToken',
|
||||
'Server',
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="server",
|
||||
old_name="ip_from",
|
||||
new_name="register_ip",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="server",
|
||||
old_name="username",
|
||||
new_name="register_username",
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="ServerGroup",
|
||||
fields=[
|
||||
@ -269,7 +279,7 @@ class Migration(migrations.Migration):
|
||||
# Add server group to transports
|
||||
migrations.AddField(
|
||||
model_name="transport",
|
||||
name="serverGroup",
|
||||
name="server_group",
|
||||
field=models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
|
@ -122,8 +122,8 @@ def migrate(
|
||||
for ip, hostname, mac in server_ip_hostname_mac:
|
||||
registeredServerGroup.servers.create(
|
||||
token=secrets.token_urlsafe(36),
|
||||
username='migration',
|
||||
ip_from='127.0.0.1',
|
||||
register_username='migration',
|
||||
register_ip='127.0.0.1',
|
||||
ip=ip,
|
||||
os_type=types.os.KnownOS.WINDOWS.os_name(),
|
||||
hostname=hostname,
|
||||
|
@ -166,9 +166,9 @@ class Server(UUIDModel, TaggingMixin, properties.PropertiesMixin):
|
||||
"""
|
||||
|
||||
# Username that registered the server
|
||||
username = models.CharField(max_length=128)
|
||||
register_username = models.CharField(max_length=128)
|
||||
# Ip from where the server was registered, can be IPv4 or IPv6
|
||||
ip_from = models.CharField(max_length=consts.system.MAX_IPV6_LENGTH)
|
||||
register_ip = models.CharField(max_length=consts.system.MAX_IPV6_LENGTH)
|
||||
# Ip of the server, can be IPv4 or IPv6 (used to communicate with it)
|
||||
ip = models.CharField(max_length=consts.system.MAX_IPV6_LENGTH)
|
||||
|
||||
@ -413,7 +413,7 @@ class Server(UUIDModel, TaggingMixin, properties.PropertiesMixin):
|
||||
return f'https://{pre}{self.ip}{post}:{self.listen_port}/{self.server_type.path()}/v1/{path}'
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'<RegisterdServer {self.token} of type {self.server_type.name} created on {self.stamp} by {self.username} from {self.ip}/{self.hostname}>'
|
||||
return f'<RegisterdServer {self.token} of type {self.server_type.name} created on {self.stamp} by {self.register_username} from {self.ip}/{self.hostname}>'
|
||||
|
||||
|
||||
properties.PropertiesMixin.setup_signals(Server)
|
||||
|
@ -64,7 +64,7 @@ class Transport(ManagedObjectModel, TaggingMixin):
|
||||
# Label, to group transports on meta pools
|
||||
label = models.CharField(max_length=32, default='', db_index=True)
|
||||
|
||||
serverGroup = models.ForeignKey(
|
||||
server_group = models.ForeignKey(
|
||||
'ServerGroup',
|
||||
related_name='transports',
|
||||
null=True,
|
||||
|
4
server/tests/fixtures/servers.py
vendored
4
server/tests/fixtures/servers.py
vendored
@ -47,8 +47,8 @@ def create_server(
|
||||
) -> 'models.Server':
|
||||
# Token is created by default on record creation
|
||||
return models.Server.objects.create(
|
||||
username=generators.random_string(),
|
||||
ip_from=ip or '127.0.0.1',
|
||||
register_username=generators.random_string(),
|
||||
register_ip=ip or '127.0.0.1',
|
||||
ip=ip or '127.0.0.1',
|
||||
hostname=generators.random_string(),
|
||||
listen_port=listen_port,
|
||||
|
211
server/tests/services/physical_machines/fixtures.py
Normal file
211
server/tests/services/physical_machines/fixtures.py
Normal file
@ -0,0 +1,211 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2024 Virtual Cable S.L.U.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""
|
||||
Author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
import contextlib
|
||||
import typing
|
||||
import uuid
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from uds import models
|
||||
from uds.core import types
|
||||
from uds.core.ui.user_interface import gui
|
||||
|
||||
SERVER_GROUP_IPS = [
|
||||
f'127.0.1.{x}' for x in range(1, 32)
|
||||
]
|
||||
|
||||
|
||||
PROVIDER_VALUES_DICT: typing.Final[gui.ValuesDictType] = {
|
||||
'config': '[wol]\n127.0.0.1/16=http://127.0.0.1:8000/test',
|
||||
}
|
||||
|
||||
|
||||
SERVICE_SINGLE_VALUES_DICT: typing.Final[gui.ValuesDictType] = {
|
||||
'host': '127.0.0.1',
|
||||
}
|
||||
|
||||
|
||||
SERVICE_MULTI_VALUES_DICT: typing.Final[gui.ValuesDictType] = {
|
||||
'token': 'MULTI_TOKEN',
|
||||
'server_group': '899bcad9-1b4d-59e3-90c7-bdd28b7674fa',
|
||||
'port': 1000, # Chekcin port
|
||||
'ignore_minutes_on_failure': 1,
|
||||
'max_session_hours': 2,
|
||||
'lock_on_external_access': True,
|
||||
'randomize_host': True,
|
||||
}
|
||||
|
||||
def create_server_group():
|
||||
server_group = models.ServerGroup.objects.create(
|
||||
name='Test Server Group',
|
||||
type=types.servers.ServerType.UNMANAGED,
|
||||
subtype=types.servers.IP_SUBTYPE,
|
||||
)
|
||||
for ip in SERVER_GROUP_IPS:
|
||||
models.Server.objects.create(
|
||||
username='test',
|
||||
name=ip,
|
||||
ip=ip,
|
||||
group=server_group,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def patched_provider(
|
||||
**kwargs: typing.Any,
|
||||
) -> typing.Generator[provider.OpenStackProvider, None, None]:
|
||||
client = create_client_mock()
|
||||
provider = create_provider(**kwargs)
|
||||
with mock.patch.object(provider, 'api') as api:
|
||||
provider.do_log = mock.MagicMock() # Avoid logging
|
||||
api.return_value = client
|
||||
yield provider
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def patched_provider_legacy(
|
||||
**kwargs: typing.Any,
|
||||
) -> typing.Generator[provider_legacy.OpenStackProviderLegacy, None, None]:
|
||||
client = create_client_mock()
|
||||
provider = create_provider_legacy(**kwargs)
|
||||
with mock.patch.object(provider, 'api') as api:
|
||||
api.return_value = client
|
||||
yield provider
|
||||
|
||||
|
||||
def create_provider(**kwargs: typing.Any) -> provider.OpenStackProvider:
|
||||
"""
|
||||
Create a provider
|
||||
"""
|
||||
values = PROVIDER_VALUES_DICT.copy()
|
||||
values.update(kwargs)
|
||||
|
||||
uuid_ = str(uuid.uuid4())
|
||||
return provider.OpenStackProvider(
|
||||
environment=environment.Environment.private_environment(uuid_), values=values, uuid=uuid_
|
||||
)
|
||||
|
||||
|
||||
def create_provider_legacy(**kwargs: typing.Any) -> provider_legacy.OpenStackProviderLegacy:
|
||||
"""
|
||||
Create a provider legacy
|
||||
"""
|
||||
values = PROVIDER_LEGACY_VALUES_DICT.copy()
|
||||
values.update(kwargs)
|
||||
|
||||
uuid_ = str(uuid.uuid4())
|
||||
return provider_legacy.OpenStackProviderLegacy(
|
||||
environment=environment.Environment.private_environment(uuid_), values=values, uuid=uuid_
|
||||
)
|
||||
|
||||
|
||||
def create_live_service(provider: AnyOpenStackProvider, **kwargs: typing.Any) -> service.OpenStackLiveService:
|
||||
"""
|
||||
Create a service
|
||||
"""
|
||||
values = SERVICE_VALUES_DICT.copy()
|
||||
values.update(kwargs)
|
||||
|
||||
uuid_ = str(uuid.uuid4())
|
||||
return service.OpenStackLiveService(
|
||||
provider=provider,
|
||||
environment=environment.Environment.private_environment(uuid_),
|
||||
values=values,
|
||||
uuid=uuid_,
|
||||
)
|
||||
|
||||
|
||||
def create_publication(service: service.OpenStackLiveService) -> publication.OpenStackLivePublication:
|
||||
"""
|
||||
Create a publication
|
||||
"""
|
||||
uuid_ = str(uuid.uuid4())
|
||||
return publication.OpenStackLivePublication(
|
||||
environment=environment.Environment.private_environment(uuid_),
|
||||
service=service,
|
||||
revision=1,
|
||||
servicepool_name='servicepool_name',
|
||||
uuid=uuid_,
|
||||
)
|
||||
|
||||
|
||||
def create_live_userservice(
|
||||
service: service.OpenStackLiveService,
|
||||
publication: typing.Optional[publication.OpenStackLivePublication] = None,
|
||||
) -> deployment.OpenStackLiveUserService:
|
||||
"""
|
||||
Create a linked user service
|
||||
"""
|
||||
uuid_ = str(uuid.uuid4())
|
||||
return deployment.OpenStackLiveUserService(
|
||||
environment=environment.Environment.private_environment(uuid_),
|
||||
service=service,
|
||||
publication=publication or create_publication(service),
|
||||
uuid=uuid_,
|
||||
)
|
||||
|
||||
|
||||
def create_fixed_service(
|
||||
provider: AnyOpenStackProvider, **kwargs: typing.Any
|
||||
) -> service_fixed.OpenStackServiceFixed:
|
||||
"""
|
||||
Create a fixed service
|
||||
"""
|
||||
values = SERVICES_FIXED_VALUES_DICT.copy()
|
||||
values.update(kwargs)
|
||||
|
||||
uuid_ = str(uuid.uuid4())
|
||||
return service_fixed.OpenStackServiceFixed(
|
||||
provider=provider,
|
||||
environment=environment.Environment.private_environment(uuid_),
|
||||
values=values,
|
||||
uuid=uuid_,
|
||||
)
|
||||
|
||||
|
||||
# Fixed has no publications
|
||||
|
||||
|
||||
def create_fixed_userservice(
|
||||
service: service_fixed.OpenStackServiceFixed,
|
||||
) -> deployment_fixed.OpenStackUserServiceFixed:
|
||||
"""
|
||||
Create a linked user service
|
||||
"""
|
||||
uuid_ = str(uuid.uuid4())
|
||||
return deployment_fixed.OpenStackUserServiceFixed(
|
||||
environment=environment.Environment.private_environment(uuid_),
|
||||
service=service,
|
||||
uuid=uuid_,
|
||||
)
|
Loading…
Reference in New Issue
Block a user