Skip to content
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

Move inband authentication controller key from host to subsystem #945

Merged
merged 1 commit into from
Nov 13, 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
88 changes: 62 additions & 26 deletions control/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,8 @@ def subsystem_add(self, args):
serial_number=args.serial_number,
max_namespaces=args.max_namespaces,
enable_ha=True,
no_group_append=args.no_group_append)
no_group_append=args.no_group_append,
dhchap_key=args.dhchap_key)
try:
ret = self.stub.create_subsystem(req)
except Exception as ex:
Expand Down Expand Up @@ -770,17 +771,18 @@ def subsystem_list(self, args):
err_func("Failure listing subsystem with serial number {args.serial_number}: Got serial number {s.serial_number} instead")
return errno.ENODEV
ctrls_id = f"{s.min_cntlid}-{s.max_cntlid}"
ha_str = "enabled" if s.enable_ha else "disabled"
one_subsys = [s.subtype, s.nqn, ha_str, s.serial_number, ctrls_id, s.namespace_count, s.max_namespaces]
has_dhchap = "Yes" if s.has_dhchap_key else "No"
allow_any = "Yes" if s.allow_any_host else "No"
one_subsys = [s.subtype, s.nqn, s.serial_number, ctrls_id, s.namespace_count, s.max_namespaces, allow_any, has_dhchap]
subsys_list.append(one_subsys)
if len(subsys_list) > 0:
if args.format == "text":
table_format = "fancy_grid"
else:
table_format = "plain"
subsys_out = tabulate(subsys_list,
headers = ["Subtype", "NQN", "HA State", "Serial\nNumber", "Controller IDs",
"Namespace\nCount", "Max\nNamespaces"],
headers = ["Subtype", "NQN", "Serial\nNumber", "Controller IDs",
"Namespace\nCount", "Max\nNamespaces", "Allow\nAny Host", "DHCHAP\nKey"],
tablefmt=table_format)
prefix = "Subsystems"
if args.subsystem:
Expand Down Expand Up @@ -815,11 +817,48 @@ def subsystem_list(self, args):

return subsystems.status

def subsystem_change_key(self, args):
"""Change subsystem's inband authentication key."""

rc = 0
out_func, err_func = self.get_output_functions(args)

req = pb2.change_subsystem_key_req(subsystem_nqn=args.subsystem, dhchap_key=args.dhchap_key)
try:
ret = self.stub.change_subsystem_key(req)
except Exception as ex:
errmsg = f"Failure changing key for subsystem {args.subsystem}"
ret = pb2.req_status(status = errno.EINVAL, error_message = f"{errmsg}:\n{ex}")

if args.format == "text" or args.format == "plain":
if ret.status == 0:
out_func(f"Changing key for subsystem {args.subsystem}: Successful")
else:
err_func(f"{ret.error_message}")
elif args.format == "json" or args.format == "yaml":
ret_str = json_format.MessageToJson(
ret,
indent=4,
including_default_value_fields=True,
preserving_proto_field_name=True)
if args.format == "json":
out_func(f"{ret_str}")
elif args.format == "yaml":
obj = json.loads(ret_str)
out_func(yaml.dump(obj))
elif args.format == "python":
return ret
else:
assert False

return ret.status

subsys_add_args = [
argument("--subsystem", "-n", help="Subsystem NQN", required=True),
argument("--serial-number", "-s", help="Serial number", required=False),
argument("--max-namespaces", "-m", help="Maximum number of namespaces", type=int, required=False),
argument("--no-group-append", help="Do not append gateway group name to the NQN", action='store_true', required=False),
argument("--dhchap-key", "-k", help="Subsystem DH-HMAC-CHAP key", required=False),
]
subsys_del_args = [
argument("--subsystem", "-n", help="Subsystem NQN", required=True),
Expand All @@ -829,10 +868,15 @@ def subsystem_list(self, args):
argument("--subsystem", "-n", help="Subsystem NQN", required=False),
argument("--serial-number", "-s", help="Serial number", required=False),
]
subsys_change_key_args = [
argument("--subsystem", "-n", help="Subsystem NQN", required=True),
argument("--dhchap-key", "-k", help="Subsystem DH-HMAC-CHAP key", required=False),
]
subsystem_actions = []
subsystem_actions.append({"name" : "add", "args" : subsys_add_args, "help" : "Create a subsystem"})
subsystem_actions.append({"name" : "del", "args" : subsys_del_args, "help" : "Delete a subsystem"})
subsystem_actions.append({"name" : "list", "args" : subsys_list_args, "help" : "List subsystems"})
subsystem_actions.append({"name" : "change_key", "args" : subsys_change_key_args, "help" : "Change subsystem key"})
subsystem_choices = get_actions(subsystem_actions)
@cli.cmd(subsystem_actions)
def subsystem(self, args):
Expand All @@ -843,6 +887,8 @@ def subsystem(self, args):
return self.subsystem_del(args)
elif args.action == "list":
return self.subsystem_list(args)
elif args.action == "change_key":
return self.subsystem_change_key(args)
if not args.action:
self.cli.parser.error(f"missing action for subsystem command (choose from {GatewayClient.subsystem_choices})")

Expand Down Expand Up @@ -1061,10 +1107,6 @@ def host_add(self, args):
if len(args.host_nqn) > 1:
self.cli.parser.error(f"Can't have more than one host NQN when DH-HMAC-CHAP keys are used")

if args.dhchap_ctrlr_key:
if not args.dhchap_key:
self.cli.parser.error(f"DH-HMAC-CHAP controller keys can not be used without DH-HMAC-CHAP keys")

for one_host_nqn in args.host_nqn:
if one_host_nqn == "*" and args.psk:
self.cli.parser.error(f"PSK key is only allowed for specific hosts")
Expand All @@ -1073,7 +1115,7 @@ def host_add(self, args):
self.cli.parser.error(f"DH-HMAC-CHAP key is only allowed for specific hosts")

req = pb2.add_host_req(subsystem_nqn=args.subsystem, host_nqn=one_host_nqn,
psk=args.psk, dhchap_key=args.dhchap_key, dhchap_ctrlr_key=args.dhchap_ctrlr_key)
psk=args.psk, dhchap_key=args.dhchap_key)
try:
ret = self.stub.add_host(req)
except Exception as ex:
Expand Down Expand Up @@ -1165,7 +1207,7 @@ def host_del(self, args):

return rc

def host_change_keys(self, args):
def host_change_key(self, args):
"""Change host's inband authentication keys."""

rc = 0
Expand All @@ -1174,21 +1216,17 @@ def host_change_keys(self, args):
if args.host_nqn == "*":
self.cli.parser.error(f"Can't change keys for host NQN '*', please use a real NQN")

if args.dhchap_ctrlr_key:
if not args.dhchap_key:
self.cli.parser.error(f"DH-HMAC-CHAP controller keys can not be used without DH-HMAC-CHAP keys")

req = pb2.change_host_keys_req(subsystem_nqn=args.subsystem, host_nqn=args.host_nqn,
dhchap_key=args.dhchap_key, dhchap_ctrlr_key=args.dhchap_ctrlr_key)
req = pb2.change_host_key_req(subsystem_nqn=args.subsystem, host_nqn=args.host_nqn,
dhchap_key=args.dhchap_key)
try:
ret = self.stub.change_host_keys(req)
ret = self.stub.change_host_key(req)
except Exception as ex:
errmsg = f"Failure changing keys for host {args.host_nqn} on subsystem {args.subsystem}"
errmsg = f"Failure changing key for host {args.host_nqn} on subsystem {args.subsystem}"
ret = pb2.req_status(status = errno.EINVAL, error_message = f"{errmsg}:\n{ex}")

if args.format == "text" or args.format == "plain":
if ret.status == 0:
out_func(f"Changing keys for host {args.host_nqn} on subsystem {args.subsystem}: Successful")
out_func(f"Changing key for host {args.host_nqn} on subsystem {args.subsystem}: Successful")
else:
err_func(f"{ret.error_message}")
elif args.format == "json" or args.format == "yaml":
Expand Down Expand Up @@ -1267,23 +1305,21 @@ def host_list(self, args):
argument("--host-nqn", "-t", help="Host NQN list", nargs="+", required=True),
argument("--psk", "-p", help="Hosts PSK key", required=False),
argument("--dhchap-key", "-k", help="Host DH-HMAC-CHAP key", required=False),
argument("--dhchap-ctrlr-key", "-c", help="Host DH-HMAC-CHAP controller key", required=False),
]
host_del_args = host_common_args + [
argument("--host-nqn", "-t", help="Host NQN list", nargs="+", required=True),
]
host_list_args = host_common_args + [
]
host_change_keys_args = host_common_args + [
host_change_key_args = host_common_args + [
argument("--host-nqn", "-t", help="Host NQN", required=True),
argument("--dhchap-key", "-k", help="Host DH-HMAC-CHAP key", required=False),
argument("--dhchap-ctrlr-key", "-c", help="Host DH-HMAC-CHAP controller key", required=False),
]
host_actions = []
host_actions.append({"name" : "add", "args" : host_add_args, "help" : "Add host access to a subsystem"})
host_actions.append({"name" : "del", "args" : host_del_args, "help" : "Remove host access from a subsystem"})
host_actions.append({"name" : "list", "args" : host_list_args, "help" : "List subsystem's host access"})
host_actions.append({"name" : "change_keys", "args" : host_change_keys_args, "help" : "Change host's inband authentication keys"})
host_actions.append({"name" : "change_key", "args" : host_change_key_args, "help" : "Change host's inband authentication keys"})
host_choices = get_actions(host_actions)
@cli.cmd(host_actions)
def host(self, args):
Expand All @@ -1294,8 +1330,8 @@ def host(self, args):
return self.host_del(args)
elif args.action == "list":
return self.host_list(args)
elif args.action == "change_keys":
return self.host_change_keys(args)
elif args.action == "change_key":
return self.host_change_key(args)
if not args.action:
self.cli.parser.error(f"missing action for host command (choose from {GatewayClient.host_choices})")

Expand Down
Loading
Loading