From 30c6c57b8fd460b3cf1faf6fd25792f0e1aa0350 Mon Sep 17 00:00:00 2001 From: Brian M Date: Fri, 17 Jan 2025 13:44:35 -0800 Subject: [PATCH] Convert iscsi.global.* to new API --- .../middlewared/api/v25_04_0/__init__.py | 1 + .../middlewared/api/v25_04_0/iscsi_global.py | 77 +++++++++++++++++++ .../plugins/iscsi_/global_linux.py | 28 ++----- .../plugins/iscsi_/iscsi_global.py | 27 ++++--- .../middlewared/plugins/iscsi_/status.py | 10 ++- 5 files changed, 109 insertions(+), 34 deletions(-) create mode 100644 src/middlewared/middlewared/api/v25_04_0/iscsi_global.py diff --git a/src/middlewared/middlewared/api/v25_04_0/__init__.py b/src/middlewared/middlewared/api/v25_04_0/__init__.py index 6627b73fc18f7..20209dfac74fe 100644 --- a/src/middlewared/middlewared/api/v25_04_0/__init__.py +++ b/src/middlewared/middlewared/api/v25_04_0/__init__.py @@ -34,6 +34,7 @@ from .initshutdownscript import * # noqa from .iscsi_auth import * # noqa from .iscsi_extent import * # noqa +from .iscsi_global import * # noqa from .iscsi_initiator import * # noqa from .iscsi_portal import * # noqa from .iscsi_target import * # noqa diff --git a/src/middlewared/middlewared/api/v25_04_0/iscsi_global.py b/src/middlewared/middlewared/api/v25_04_0/iscsi_global.py new file mode 100644 index 0000000000000..743ef6dea2d9f --- /dev/null +++ b/src/middlewared/middlewared/api/v25_04_0/iscsi_global.py @@ -0,0 +1,77 @@ +from pydantic import Field + +from middlewared.api.base import BaseModel, Excluded, excluded_field, ForUpdateMetaclass, single_argument_args +from .common import QueryFilters, QueryOptions + +__all__ = [ + "IscsiGlobalEntry", + "IscsiGlobalUpdateArgs", + "IscsiGlobalUpdateResult", + "IscsiGlobalAluaEnabledArgs", + "IscsiGlobalAluaEnabledResult", + "IscsiGlobalClientCountArgs", + "IscsiGlobalClientCountResult", + "IscsiGlobalSessionsArgs", + "IscsiGlobalSessionsResult" +] + + +class IscsiGlobalEntry(BaseModel): + id: int + basename: str + isns_servers: list[str] + listen_port: int = Field(ge=1025, le=65535, default=3260) + pool_avail_threshold: int | None = Field(ge=1, le=99, default=None) + alua: bool + + +@single_argument_args('iscsi_update') +class IscsiGlobalUpdateArgs(IscsiGlobalEntry, metaclass=ForUpdateMetaclass): + id: Excluded = excluded_field() + + +class IscsiGlobalUpdateResult(BaseModel): + result: IscsiGlobalEntry + + +class IscsiGlobalAluaEnabledArgs(BaseModel): + pass + + +class IscsiGlobalAluaEnabledResult(BaseModel): + result: bool + + +class IscsiGlobalClientCountArgs(BaseModel): + pass + + +class IscsiGlobalClientCountResult(BaseModel): + result: int + + +class IscsiSession(BaseModel): + initiator: str + initiator_addr: str + initiator_alias: str | None + target: str + target_alias: str + header_digest: str | None + data_digest: str | None + max_data_segment_length: int | None + max_receive_data_segment_length: int | None + max_xmit_data_segment_length: int | None + max_burst_length: int | None + first_burst_length: int | None + immediate_data: bool + iser: bool + offload: bool + + +class IscsiGlobalSessionsArgs(BaseModel): + query_filters: QueryFilters = [] + query_options: QueryOptions = QueryOptions() + + +class IscsiGlobalSessionsResult(BaseModel): + result: list[IscsiSession] diff --git a/src/middlewared/middlewared/plugins/iscsi_/global_linux.py b/src/middlewared/middlewared/plugins/iscsi_/global_linux.py index 07653f4619512..f109f8368701d 100644 --- a/src/middlewared/middlewared/plugins/iscsi_/global_linux.py +++ b/src/middlewared/middlewared/plugins/iscsi_/global_linux.py @@ -1,8 +1,9 @@ import glob import os -from middlewared.schema import Bool, Dict, Int, Str -from middlewared.service import filterable, filterable_returns, private, Service +from middlewared.api import api_method +from middlewared.api.current import IscsiGlobalSessionsArgs, IscsiGlobalSessionsResult +from middlewared.service import private, Service from middlewared.service_exception import MatchNotFound from middlewared.utils import filter_list, run @@ -12,24 +13,11 @@ class ISCSIGlobalService(Service): class Config: namespace = 'iscsi.global' - @filterable(roles=['SHARING_ISCSI_GLOBAL_READ']) - @filterable_returns(Dict( - 'session', - Str('initiator'), - Str('initiator_addr'), - Str('initiator_alias', null=True), - Str('target'), - Str('target_alias'), - Str('header_digest', null=True), - Str('data_digest', null=True), - Int('max_data_segment_length', null=True), - Int('max_receive_data_segment_length', null=True), - Int('max_burst_length', null=True), - Int('first_burst_length', null=True), - Bool('immediate_data'), - Bool('iser'), - Bool('offload'), - )) + @api_method( + IscsiGlobalSessionsArgs, + IscsiGlobalSessionsResult, + roles=['SHARING_ISCSI_GLOBAL_READ'] + ) def sessions(self, filters, options): """ Get a list of currently running iSCSI sessions. This includes initiator and target names diff --git a/src/middlewared/middlewared/plugins/iscsi_/iscsi_global.py b/src/middlewared/middlewared/plugins/iscsi_/iscsi_global.py index bb7c05ffb14c4..8c474019a6926 100644 --- a/src/middlewared/middlewared/plugins/iscsi_/iscsi_global.py +++ b/src/middlewared/middlewared/plugins/iscsi_/iscsi_global.py @@ -3,11 +3,13 @@ import socket import middlewared.sqlalchemy as sa +from middlewared.api import api_method +from middlewared.api.current import (IscsiGlobalAluaEnabledArgs, IscsiGlobalAluaEnabledResult, IscsiGlobalEntry, + IscsiGlobalUpdateArgs, IscsiGlobalUpdateResult) from middlewared.async_validators import validate_port -from middlewared.schema import Bool, Dict, Int, List, Str, accepts from middlewared.service import SystemServiceService, ValidationErrors, private from middlewared.utils import run -from middlewared.validators import IpAddress, Port, Range +from middlewared.validators import IpAddress, Port RE_IP_PORT = re.compile(r'^(.+?)(:[0-9]+)?$') @@ -33,6 +35,7 @@ class Config: namespace = 'iscsi.global' cli_namespace = 'sharing.iscsi.global' role_prefix = 'SHARING_ISCSI_GLOBAL' + entry = IscsiGlobalEntry @private def port_is_listening(self, host, port, timeout=5): @@ -98,15 +101,11 @@ def config_extend(self, data): data['isns_servers'] = data['isns_servers'].split() return data - @accepts(Dict( - 'iscsiglobal_update', - Str('basename'), - List('isns_servers', items=[Str('server')]), - Int('listen_port', validators=[Range(min_=1025, max_=65535)], default=3260), - Int('pool_avail_threshold', validators=[Range(min_=1, max_=99)], null=True), - Bool('alua'), - update=True - ), audit='Update iSCSI') + @api_method( + IscsiGlobalUpdateArgs, + IscsiGlobalUpdateResult, + audit='Update iSCSI' + ) async def do_update(self, data): """ `alua` is a no-op for FreeNAS. @@ -183,7 +182,11 @@ async def stop_active_isns(self): if cp.returncode: self.logger.warning('Failed to stop active iSNS: %s', cp.stderr.decode()) - @accepts(roles=['SHARING_ISCSI_GLOBAL_READ']) + @api_method( + IscsiGlobalAluaEnabledArgs, + IscsiGlobalAluaEnabledResult, + roles=['SHARING_ISCSI_GLOBAL_READ'] + ) async def alua_enabled(self): """ Returns whether iSCSI ALUA is enabled or not. diff --git a/src/middlewared/middlewared/plugins/iscsi_/status.py b/src/middlewared/middlewared/plugins/iscsi_/status.py index aa5c2082dda59..b5068151abf1d 100644 --- a/src/middlewared/middlewared/plugins/iscsi_/status.py +++ b/src/middlewared/middlewared/plugins/iscsi_/status.py @@ -1,4 +1,6 @@ -from middlewared.service import accepts, Service +from middlewared.api import api_method +from middlewared.api.current import IscsiGlobalClientCountArgs, IscsiGlobalClientCountResult +from middlewared.service import Service class ISCSIGlobalService(Service): @@ -7,7 +9,11 @@ class Config: namespace = 'iscsi.global' cli_namespace = 'sharing.iscsi.global' - @accepts(roles=['SHARING_ISCSI_GLOBAL_READ']) + @api_method( + IscsiGlobalClientCountArgs, + IscsiGlobalClientCountResult, + roles=['SHARING_ISCSI_GLOBAL_READ'] + ) async def client_count(self): """ Return currently connected clients count.