@@ -1067,9 +1067,7 @@ def host_add(self, args):
1067
1067
if not args .dhchap_key :
1068
1068
self .cli .parser .error (f"DH-HMAC-CHAP controller keys can not be used without DH-HMAC-CHAP keys" )
1069
1069
1070
- for i in range (len (args .host_nqn )):
1071
- one_host_nqn = args .host_nqn [i ]
1072
-
1070
+ for one_host_nqn in args .host_nqn :
1073
1071
if one_host_nqn == "*" and args .psk :
1074
1072
self .cli .parser .error (f"PSK key is only allowed for specific hosts" )
1075
1073
@@ -1360,7 +1358,8 @@ def ns_add(self, args):
1360
1358
anagrpid = args .load_balancing_group ,
1361
1359
create_image = args .rbd_create_image ,
1362
1360
size = img_size ,
1363
- force = args .force )
1361
+ force = args .force ,
1362
+ no_auto_visible = args .no_auto_visible )
1364
1363
try :
1365
1364
ret = self .stub .namespace_add (req )
1366
1365
except Exception as ex :
@@ -1547,6 +1546,15 @@ def ns_list(self, args):
1547
1546
lb_group = "<n/a>"
1548
1547
else :
1549
1548
lb_group = str (ns .load_balancing_group )
1549
+ if ns .no_auto_visible :
1550
+ if len (ns .hosts ) > 0 :
1551
+ for hst in ns .hosts :
1552
+ visibility = break_string (hst , ":" , 2 ) + "\n "
1553
+ else :
1554
+ visibility = "Selective"
1555
+ else :
1556
+ visibility = "All Hosts"
1557
+
1550
1558
namespaces_list .append ([ns .nsid ,
1551
1559
break_string (ns .bdev_name , "-" , 2 ),
1552
1560
ns .rbd_pool_name ,
@@ -1555,6 +1563,7 @@ def ns_list(self, args):
1555
1563
self .format_size (ns .block_size ),
1556
1564
break_string (ns .uuid , "-" , 3 ),
1557
1565
lb_group ,
1566
+ visibility ,
1558
1567
self .get_qos_limit_str_value (ns .rw_ios_per_second ),
1559
1568
self .get_qos_limit_str_value (ns .rw_mbytes_per_second ),
1560
1569
self .get_qos_limit_str_value (ns .r_mbytes_per_second ),
@@ -1567,7 +1576,7 @@ def ns_list(self, args):
1567
1576
table_format = "plain"
1568
1577
namespaces_out = tabulate (namespaces_list ,
1569
1578
headers = ["NSID" , "Bdev\n Name" , "RBD\n Pool" , "RBD\n Image" ,
1570
- "Image\n Size" , "Block\n Size" , "UUID" , "Load\n Balancing\n Group" ,
1579
+ "Image\n Size" , "Block\n Size" , "UUID" , "Load\n Balancing\n Group" , "Visibility" ,
1571
1580
"R/W IOs\n per\n second" , "R/W MBs\n per\n second" ,
1572
1581
"Read MBs\n per\n second" , "Write MBs\n per\n second" ],
1573
1582
tablefmt = table_format )
@@ -1809,6 +1818,98 @@ def ns_set_qos(self, args):
1809
1818
1810
1819
return ret .status
1811
1820
1821
+ def ns_add_host (self , args ):
1822
+ """Adds a host to a namespace."""
1823
+
1824
+ rc = 0
1825
+ ret_list = []
1826
+ out_func , err_func = self .get_output_functions (args )
1827
+
1828
+ if args .nsid <= 0 :
1829
+ self .cli .parser .error ("nsid value must be positive" )
1830
+
1831
+ for one_host_nqn in args .host_nqn :
1832
+ try :
1833
+ add_host_req = pb2 .namespace_add_host_req (subsystem_nqn = args .subsystem , nsid = args .nsid , host_nqn = one_host_nqn )
1834
+ ret = self .stub .namespace_add_host (add_host_req )
1835
+ except Exception as ex :
1836
+ ret = pb2 .req_status (status = errno .EINVAL , error_message = f"Failure adding host to namespace:\n { ex } " )
1837
+
1838
+ if not rc :
1839
+ rc = ret .status
1840
+
1841
+ if args .format == "text" or args .format == "plain" :
1842
+ if ret .status == 0 :
1843
+ out_func (f"Adding host { one_host_nqn } to namespace { args .nsid } on { args .subsystem } : Successful" )
1844
+ else :
1845
+ err_func (f"{ ret .error_message } " )
1846
+ elif args .format == "json" or args .format == "yaml" :
1847
+ ret_str = json_format .MessageToJson (
1848
+ ret ,
1849
+ indent = 4 ,
1850
+ including_default_value_fields = True ,
1851
+ preserving_proto_field_name = True )
1852
+ if args .format == "json" :
1853
+ out_func (f"{ ret_str } " )
1854
+ elif args .format == "yaml" :
1855
+ obj = json .loads (ret_str )
1856
+ out_func (yaml .dump (obj ))
1857
+ elif args .format == "python" :
1858
+ ret_list .append (ret )
1859
+ else :
1860
+ assert False
1861
+
1862
+ if args .format == "python" :
1863
+ return ret_list
1864
+
1865
+ return rc
1866
+
1867
+ def ns_del_host (self , args ):
1868
+ """Deletes a host from a namespace."""
1869
+
1870
+ rc = 0
1871
+ ret_list = []
1872
+ out_func , err_func = self .get_output_functions (args )
1873
+
1874
+ if args .nsid <= 0 :
1875
+ self .cli .parser .error ("nsid value must be positive" )
1876
+
1877
+ for one_host_nqn in args .host_nqn :
1878
+ try :
1879
+ del_host_req = pb2 .namespace_delete_host_req (subsystem_nqn = args .subsystem , nsid = args .nsid , host_nqn = one_host_nqn )
1880
+ ret = self .stub .namespace_delete_host (del_host_req )
1881
+ except Exception as ex :
1882
+ ret = pb2 .req_status (status = errno .EINVAL , error_message = f"Failure deleting host from namespace:\n { ex } " )
1883
+
1884
+ if not rc :
1885
+ rc = ret .status
1886
+
1887
+ if args .format == "text" or args .format == "plain" :
1888
+ if ret .status == 0 :
1889
+ out_func (f"Deleting host { args .host_nqn } from namespace { args .nsid } on { args .subsystem } : Successful" )
1890
+ else :
1891
+ err_func (f"{ ret .error_message } " )
1892
+ elif args .format == "json" or args .format == "yaml" :
1893
+ ret_str = json_format .MessageToJson (
1894
+ ret ,
1895
+ indent = 4 ,
1896
+ including_default_value_fields = True ,
1897
+ preserving_proto_field_name = True )
1898
+ if args .format == "json" :
1899
+ out_func (f"{ ret_str } " )
1900
+ elif args .format == "yaml" :
1901
+ obj = json .loads (ret_str )
1902
+ out_func (yaml .dump (obj ))
1903
+ elif args .format == "python" :
1904
+ ret_list .append (ret )
1905
+ else :
1906
+ assert False
1907
+
1908
+ if args .format == "python" :
1909
+ return ret_list
1910
+
1911
+ return rc
1912
+
1812
1913
ns_common_args = [
1813
1914
argument ("--subsystem" , "-n" , help = "Subsystem NQN" , required = True ),
1814
1915
]
@@ -1821,7 +1922,8 @@ def ns_set_qos(self, args):
1821
1922
argument ("--block-size" , "-s" , help = "Block size" , type = int ),
1822
1923
argument ("--load-balancing-group" , "-l" , help = "Load balancing group" , type = int , default = 0 ),
1823
1924
argument ("--size" , help = "Size in bytes or specified unit (K, KB, M, MB, G, GB, T, TB, P, PB)" ),
1824
- argument ("--force" , help = "Create a namespace even its image is already used by another namespace" , action = 'store_true' , required = False ),
1925
+ argument ("--force" , help = "Create a namespace even when its image is already used by another namespace" , action = 'store_true' , required = False ),
1926
+ argument ("--no-auto-visible" , help = "Make the namespace visible only to specific hosts" , action = 'store_true' , required = False ),
1825
1927
]
1826
1928
ns_del_args_list = ns_common_args + [
1827
1929
argument ("--nsid" , help = "Namespace ID" , type = int , required = True ),
@@ -1848,6 +1950,14 @@ def ns_set_qos(self, args):
1848
1950
argument ("--r-megabytes-per-second" , help = "Read megabytes per second limit, 0 means unlimited" , type = int ),
1849
1951
argument ("--w-megabytes-per-second" , help = "Write megabytes per second limit, 0 means unlimited" , type = int ),
1850
1952
]
1953
+ ns_add_host_args_list = ns_common_args + [
1954
+ argument ("--nsid" , help = "Namespace ID" , type = int , required = True ),
1955
+ argument ("--host-nqn" , "-t" , help = "Host NQN list" , nargs = "+" , required = True ),
1956
+ ]
1957
+ ns_del_host_args_list = ns_common_args + [
1958
+ argument ("--nsid" , help = "Namespace ID" , type = int , required = True ),
1959
+ argument ("--host-nqn" , "-t" , help = "Host NQN list" , nargs = "+" , required = True ),
1960
+ ]
1851
1961
ns_actions = []
1852
1962
ns_actions .append ({"name" : "add" , "args" : ns_add_args_list , "help" : "Create a namespace" })
1853
1963
ns_actions .append ({"name" : "del" , "args" : ns_del_args_list , "help" : "Delete a namespace" })
@@ -1856,6 +1966,8 @@ def ns_set_qos(self, args):
1856
1966
ns_actions .append ({"name" : "get_io_stats" , "args" : ns_get_io_stats_args_list , "help" : "Get I/O stats for a namespace" })
1857
1967
ns_actions .append ({"name" : "change_load_balancing_group" , "args" : ns_change_load_balancing_group_args_list , "help" : "Change load balancing group for a namespace" })
1858
1968
ns_actions .append ({"name" : "set_qos" , "args" : ns_set_qos_args_list , "help" : "Set QOS limits for a namespace" })
1969
+ ns_actions .append ({"name" : "add_host" , "args" : ns_add_host_args_list , "help" : "Add a host to a namespace" })
1970
+ ns_actions .append ({"name" : "del_host" , "args" : ns_del_host_args_list , "help" : "Delete a host from a namespace" })
1859
1971
ns_choices = get_actions (ns_actions )
1860
1972
@cli .cmd (ns_actions , ["ns" ])
1861
1973
def namespace (self , args ):
@@ -1874,6 +1986,10 @@ def namespace(self, args):
1874
1986
return self .ns_change_load_balancing_group (args )
1875
1987
elif args .action == "set_qos" :
1876
1988
return self .ns_set_qos (args )
1989
+ elif args .action == "add_host" :
1990
+ return self .ns_add_host (args )
1991
+ elif args .action == "del_host" :
1992
+ return self .ns_del_host (args )
1877
1993
if not args .action :
1878
1994
self .cli .parser .error (f"missing action for namespace command (choose from { GatewayClient .ns_choices } )" )
1879
1995
0 commit comments