Skip to content

Check subsystem and host NQN validity before passing them to SPDK #381

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 22, 2024
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 ceph-nvmeof.conf
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ log_level=debug
#prometheus_port = 10008
#prometheus_bdev_pools = rbd
#prometheus_stats_interval = 10
#verify_nqns = True

[discovery]
addr = 0.0.0.0
Expand Down
59 changes: 29 additions & 30 deletions control/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
from .proto import gateway_pb2_grpc as pb2_grpc
from .proto import gateway_pb2 as pb2
from .config import GatewayConfig
from .config import GatewayEnumUtils
from .utils import GatewayUtils
from .utils import GatewayEnumUtils

BASE_GATEWAY_VERSION="0.0.7"

Expand Down Expand Up @@ -187,7 +188,7 @@ def stub(self):
def connect(self, host, port, client_key, client_cert, server_cert):
"""Connects to server and sets stub."""
# We need to enclose IPv6 addresses in brackets before concatenating a colon and port number to it
host = GatewayConfig.escape_address_if_ipv6(host)
host = GatewayUtils.escape_address_if_ipv6(host)
server = f"{host}:{port}"

if client_key and client_cert:
Expand Down Expand Up @@ -550,15 +551,15 @@ def subsystem_add(self, args):
out_func, err_func = self.get_output_functions(args)
if args.max_namespaces == None:
args.max_namespaces = 256
if args.max_namespaces < 0:
if args.max_namespaces <= 0:
self.cli.parser.error("--max-namespaces value must be positive")
if not args.subsystem:
self.cli.parser.error("--subsystem argument is mandatory for add command")
if args.force:
self.cli.parser.error("--force argument is not allowed for add command")
if args.enable_ha and not args.ana_reporting:
self.cli.parser.error("ANA reporting must be enabled when HA is active")
if args.subsystem == GatewayConfig.DISCOVERY_NQN:
if args.subsystem == GatewayUtils.DISCOVERY_NQN:
self.cli.parser.error("Can't add a discovery subsystem")

req = pb2.create_subsystem_req(subsystem_nqn=args.subsystem,
Expand Down Expand Up @@ -608,7 +609,7 @@ def subsystem_del(self, args):
self.cli.parser.error("--ana-reporting argument is not allowed for del command")
if args.enable_ha:
self.cli.parser.error("--enable-ha argument is not allowed for del command")
if args.subsystem == GatewayConfig.DISCOVERY_NQN:
if args.subsystem == GatewayUtils.DISCOVERY_NQN:
self.cli.parser.error("Can't delete a discovery subsystem")

req = pb2.delete_subsystem_req(subsystem_nqn=args.subsystem, force=args.force)
Expand Down Expand Up @@ -743,16 +744,16 @@ def listener_add(self, args):
if not args.traddr:
self.cli.parser.error("--traddr argument is mandatory for add command")

if not args.trsvcid:
if args.trsvcid == None:
args.trsvcid = 4420
elif args.trsvcid < 0:
elif args.trsvcid <= 0:
self.cli.parser.error("trsvcid value must be positive")
if not args.trtype:
args.trtype = "TCP"
if not args.adrfam:
args.adrfam = "IPV4"

traddr = GatewayConfig.escape_address_if_ipv6(args.traddr)
traddr = GatewayUtils.escape_address_if_ipv6(args.traddr)
trtype = None
adrfam = None
if args.trtype:
Expand Down Expand Up @@ -807,16 +808,16 @@ def listener_del(self, args):
self.cli.parser.error("--gateway-name argument is mandatory for del command")
if not args.traddr:
self.cli.parser.error("--traddr argument is mandatory for del command")
if not args.trsvcid:
if args.trsvcid == None:
self.cli.parser.error("--trsvcid argument is mandatory for del command")
if args.trsvcid < 0:
if args.trsvcid <= 0:
self.cli.parser.error("trsvcid value must be positive")
if not args.trtype:
args.trtype = "TCP"
if not args.adrfam:
args.adrfam = "IPV4"

traddr = GatewayConfig.escape_address_if_ipv6(args.traddr)
traddr = GatewayUtils.escape_address_if_ipv6(args.traddr)
trtype = None
adrfam = None
if args.trtype:
Expand Down Expand Up @@ -874,7 +875,7 @@ def listener_list(self, args):
self.cli.parser.error("--trtype argument is not allowed for list command")
if args.adrfam:
self.cli.parser.error("--adrfam argument is not allowed for list command")
if args.trsvcid:
if args.trsvcid != None:
self.cli.parser.error("--trsvcid argument is not allowed for list command")

listeners_info = None
Expand Down Expand Up @@ -1161,9 +1162,9 @@ def ns_add(self, args):
args.block_size = 512
if args.load_balancing_group == None:
args.load_balancing_group = 1
if args.load_balancing_group and args.load_balancing_group < 0:
if args.load_balancing_group <= 0:
self.cli.parser.error("load-balancing-group value must be positive")
if args.nsid and args.nsid <= 0:
if args.nsid != None and args.nsid <= 0:
self.cli.parser.error("nsid value must be positive")
if args.size != None:
self.cli.parser.error("--size argument is not allowed for add command")
Expand All @@ -1173,8 +1174,6 @@ def ns_add(self, args):
self.cli.parser.error("--rbd-image argument is mandatory for add command")
if args.block_size <= 0:
self.cli.parser.error("block-size value must be positive")
if args.load_balancing_group <= 0:
self.cli.parser.error("load-balancing-group value must be positive")
if args.rw_ios_per_second != None:
self.cli.parser.error("--rw-ios-per-second argument is not allowed for add command")
if args.rw_megabytes_per_second != None:
Expand Down Expand Up @@ -1227,9 +1226,9 @@ def ns_del(self, args):
"""Deletes a namespace from a subsystem."""

out_func, err_func = self.get_output_functions(args)
if not args.nsid and not args.uuid:
if args.nsid == None and args.uuid == None:
self.cli.parser.error("At least one of --nsid or --uuid arguments is mandatory for del command")
if args.nsid and args.nsid < 0:
if args.nsid != None and args.nsid <= 0:
self.cli.parser.error("nsid value must be positive")
if args.size != None:
self.cli.parser.error("--size argument is not allowed for del command")
Expand All @@ -1239,7 +1238,7 @@ def ns_del(self, args):
self.cli.parser.error("--rbd-pool argument is not allowed for del command")
if args.rbd_image != None:
self.cli.parser.error("--rbd-image argument is not allowed for del command")
if args.load_balancing_group:
if args.load_balancing_group != None:
self.cli.parser.error("--load-balancing-group argument is not allowed for del command")
if args.rw_ios_per_second != None:
self.cli.parser.error("--rw-ios-per-second argument is not allowed for del command")
Expand Down Expand Up @@ -1288,13 +1287,13 @@ def ns_resize(self, args):
"""Resizes a namespace."""

out_func, err_func = self.get_output_functions(args)
if not args.nsid and not args.uuid:
if args.nsid == None and args.uuid == None:
self.cli.parser.error("At least one of --nsid or --uuid arguments is mandatory for resize command")
if args.nsid and args.nsid < 0:
if args.nsid != None and args.nsid <= 0:
self.cli.parser.error("nsid value must be positive")
if not args.size:
if args.size == None:
self.cli.parser.error("--size argument is mandatory for resize command")
if args.size < 0:
if args.size <= 0:
self.cli.parser.error("size value must be positive")
if args.block_size != None:
self.cli.parser.error("--block-size argument is not allowed for resize command")
Expand Down Expand Up @@ -1379,7 +1378,7 @@ def ns_list(self, args):
"""Lists namespaces on a subsystem."""

out_func, err_func = self.get_output_functions(args)
if args.nsid and args.nsid < 0:
if args.nsid != None and args.nsid <= 0:
self.cli.parser.error("nsid value must be positive")
if args.size != None:
self.cli.parser.error("--size argument is not allowed for list command")
Expand Down Expand Up @@ -1486,9 +1485,9 @@ def ns_get_io_stats(self, args):
"""Get namespace IO statistics."""

out_func, err_func = self.get_output_functions(args)
if not args.nsid and not args.uuid:
if args.nsid == None and args.uuid == None:
self.cli.parser.error("At least one of --nsid or --uuid arguments is mandatory for get_io_stats command")
if args.nsid and args.nsid < 0:
if args.nsid != None and args.nsid <= 0:
self.cli.parser.error("nsid value must be positive")
if args.size != None:
self.cli.parser.error("--size argument is not allowed for get_io_stats command")
Expand Down Expand Up @@ -1587,9 +1586,9 @@ def ns_change_load_balancing_group(self, args):
"""Change namespace load balancing group."""

out_func, err_func = self.get_output_functions(args)
if not args.nsid and not args.uuid:
if args.nsid == None and args.uuid == None:
self.cli.parser.error("At least one of --nsid or --uuid arguments is mandatory for change_load_balancing_group command")
if args.nsid and args.nsid < 0:
if args.nsid != None and args.nsid <= 0:
self.cli.parser.error("nsid value must be positive")
if args.load_balancing_group == None:
self.cli.parser.error("--load-balancing-group argument is mandatory for change_load_balancing_group command")
Expand Down Expand Up @@ -1659,9 +1658,9 @@ def ns_set_qos(self, args):
"""Set namespace QOS limits."""

out_func, err_func = self.get_output_functions(args)
if not args.nsid and not args.uuid:
if args.nsid == None and args.uuid == None:
self.cli.parser.error("At least one of --nsid or --uuid arguments is mandatory for set_qos command")
if args.nsid and args.nsid < 0:
if args.nsid != None and args.nsid <= 0:
self.cli.parser.error("nsid value must be positive")
if args.load_balancing_group != None:
self.cli.parser.error("--load-balancing-group argument is not allowed for set_qos command")
Expand Down
37 changes: 0 additions & 37 deletions control/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,43 +15,13 @@
import gzip
import shutil

class GatewayEnumUtils:
def get_value_from_key(e_type, keyval, ignore_case = False):
val = None
try:
key_index = e_type.keys().index(keyval)
val = e_type.values()[key_index]
except ValueError:
pass
except IndexError:
pass

if ignore_case and val == None and type(keyval) == str:
val = get_value_from_key(e_type, keyval.lower(), False)
if ignore_case and val == None and type(keyval) == str:
val = get_value_from_key(e_type, keyval.upper(), False)

return val

def get_key_from_value(e_type, val):
keyval = None
try:
val_index = e_type.values().index(val)
keyval = e_type.keys()[val_index]
except ValueError:
pass
except IndexError:
pass
return keyval

class GatewayConfig:
"""Loads and returns config file settings.

Instance attributes:
config: Config parser object
"""

DISCOVERY_NQN = "nqn.2014-08.org.nvmexpress.discovery"
CEPH_RUN_DIRECTORY = "/var/run/ceph/"

def __init__(self, conffile):
Expand Down Expand Up @@ -103,13 +73,6 @@ def dump_config_file(self, logger):
except Exception:
pass

# We need to enclose IPv6 addresses in brackets before concatenating a colon and port number to it
def escape_address_if_ipv6(addr) -> str:
ret_addr = addr
if ":" in addr and not addr.strip().startswith("["):
ret_addr = f"[{addr}]"
return ret_addr

class GatewayLogger:
CEPH_LOG_DIRECTORY = "/var/log/ceph/"
MAX_LOG_FILE_SIZE_DEFAULT = 10
Expand Down
2 changes: 1 addition & 1 deletion control/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import logging
from .config import GatewayConfig
from .state import GatewayState, LocalGatewayState, OmapGatewayState, GatewayStateHandler
from .config import GatewayEnumUtils
from .utils import GatewayEnumUtils
from .config import GatewayLogger
from .proto import gateway_pb2 as pb2

Expand Down
Loading