Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
779b906
debug
uriziv1 Nov 18, 2025
498fdd9
debug
uriziv1 Nov 18, 2025
0cc541d
debug
uriziv1 Nov 20, 2025
bc581a0
get crd info
uriziv1 Nov 20, 2025
c8aab58
pylint
uriziv1 Nov 20, 2025
35a70ee
pylint
uriziv1 Nov 20, 2025
d611b27
get_crds_info
uriziv1 Nov 20, 2025
f989841
get_crds_info
uriziv1 Nov 20, 2025
bfc15bb
test
uriziv1 Nov 23, 2025
c4b6254
test
uriziv1 Nov 23, 2025
5a5674a
test
uriziv1 Nov 23, 2025
a95a177
syntax
uriziv1 Nov 23, 2025
50b99fa
test
uriziv1 Nov 23, 2025
3e1fbae
items()
uriziv1 Nov 23, 2025
324510a
DEBUG - request
uriziv1 Nov 23, 2025
e3e5023
test
uriziv1 Nov 23, 2025
5297d6e
debug
uriziv1 Nov 23, 2025
1367677
debug
uriziv1 Nov 23, 2025
ebf2f27
debug comments to consider
uriziv1 Nov 25, 2025
b88c315
CrdWatcher
uriziv1 Nov 25, 2025
c358a26
UpdateNodePortsAnnotation
uriziv1 Nov 25, 2025
8e52478
TestNodeGetInfo - fakeNodeutils.EXPECT().UpdateNodePortsAnnotation
uriziv1 Nov 25, 2025
5d2a5f8
debug
uriziv1 Nov 27, 2025
09bb0a4
host definer side
uriziv1 Nov 30, 2025
30640cc
Revert "CrdWatcher"
uriziv1 Nov 30, 2025
6ffcdc7
remred
uriziv1 Nov 30, 2025
3d9f3c6
remred
uriziv1 Nov 30, 2025
06f4b4b
remred
uriziv1 Nov 30, 2025
cb0f15d
debug
uriziv1 Dec 1, 2025
6743779
adapt unitest for new functions:
uriziv1 Dec 1, 2025
e709d19
fix unitest - ValueError: node id has wrong format
uriziv1 Dec 1, 2025
3aa7c5b
fix unitest - ValueError: node id has wrong format
uriziv1 Dec 1, 2025
a076400
unitest - ./controllers/servers/host_definer/kubernetes_manager/manag…
uriziv1 Dec 3, 2025
ed6e644
unitest - ValueError: node id has wrong format
uriziv1 Dec 3, 2025
00f5358
debug
uriziv1 Dec 3, 2025
54a2737
controller_server
uriziv1 Dec 4, 2025
281d02d
mock_get_node_initiators
uriziv1 Dec 4, 2025
8e6fd9f
unitest - C0301: Line too long (127/120) (line-too-long)
uriziv1 Dec 4, 2025
2dd6669
unitest - E302 expected 2 blank lines, found 1
uriziv1 Dec 4, 2025
60f2602
unitest - fix mock path
uriziv1 Dec 4, 2025
81556e2
pip install kubernetes inside controller image
uriziv1 Dec 4, 2025
e7a052f
remred
uriziv1 Dec 8, 2025
fcaf197
refc - short funcs
uriziv1 Dec 8, 2025
ba8f72c
Remove GenerateNodeID func
uriziv1 Dec 10, 2025
290161e
syntax
uriziv1 Dec 10, 2025
423f3c9
Jenkins - Prevent go test deadlock by decoupling go2xunit pipe
uriziv1 Dec 10, 2025
3eac7c3
order
uriziv1 Dec 10, 2025
7034a17
Jenkins - Prevent unit test pipe deadlock and ensure XUnit reporting
uriziv1 Dec 10, 2025
ea15055
Jenkins - improve
uriziv1 Dec 10, 2025
743c27e
unitest
uriziv1 Dec 10, 2025
f138472
refactor initiators - part1
uriziv1 Dec 16, 2025
ba1210b
tmp disable ut for refactor initiators - part1
uriziv1 Dec 16, 2025
b4c8e44
AFTER MARGE TO 1.13.1 - unitest fixes
uriziv1 Dec 17, 2025
def389d
debug
uriziv1 Dec 17, 2025
e0e16be
debug
uriziv1 Dec 17, 2025
a308825
debug
uriziv1 Dec 17, 2025
370cd1f
UNITEST - disable test_pending_creation_that_managed_to_be_created
uriziv1 Dec 17, 2025
0bcb50d
UNITEST - disable test_pending_creation_that_managed_to_be_created
uriziv1 Dec 17, 2025
f27a904
JENKINS - UNITEST: Temporarily Skip: Controllers: Unit testing + cove…
uriziv1 Dec 18, 2025
209652d
JENKINS - UNITEST: Temporarily Skip: Controllers: Unit testing + cove…
uriziv1 Dec 18, 2025
0658d6a
Revert "JENKINS - UNITEST: Temporarily Skip: Controllers: Unit testin…
uriziv1 Dec 18, 2025
67df5ce
JENKINS - UNITEST: Temporarily Skip: Controllers: Unit testing + cove…
uriziv1 Dec 18, 2025
cd6fa74
host definer - add_initiators_to_request
uriziv1 Dec 18, 2025
8ad78e9
remred
uriziv1 Dec 18, 2025
b9709f7
debug
uriziv1 Dec 27, 2025
96eae3d
debug
uriziv1 Dec 27, 2025
eafe7c0
debug
uriziv1 Dec 28, 2025
3a467d3
Add node_initiators to DefineHostRequest
uriziv1 Dec 28, 2025
cbe260b
debug
uriziv1 Dec 28, 2025
b39e785
get initiators from host definition request and by func _get_initiato…
uriziv1 Dec 28, 2025
463f460
todo
uriziv1 Dec 28, 2025
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
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ test-xunit:
go generate ./...
$(gofmt-test)
go vet -c=1 ./node/...
go test ${GO_TEST_FLAGS} ./node/... | go2xunit -output build/reports/csi-node-unitests.xml
go test ${GO_TEST_FLAGS} ./node/... 2>&1 > ./build/reports/test_raw.txt || true
cat ./build/reports/test_raw.txt | go2xunit -output build/reports/csi-node-unitests.xml
go test ${GO_TEST_FLAGS} ./node/... # run again so the makefile will fail in case tests failing

.PHONY: test-xunit-in-container
Expand Down
1 change: 0 additions & 1 deletion common/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ parameters:
delimiter: ":"
ids_delimiter: ";"
node_id_info:
delimiter: ";"
fcs_delimiter: ":"

connectivity_type:
Expand Down
9 changes: 3 additions & 6 deletions controllers/common/node_info.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from dataclasses import dataclass, field

import controllers.servers.settings as servers_settings
from controllers.array_action import settings as array_config
from controllers.common import utils


class NodeIdInfo:
Expand All @@ -11,16 +9,15 @@ def __init__(self, node_id):
Args:
node_id: <node_name>,<iqn>,<wwns>
"""
node_name, nvme_nqn, fc_wwns_str, iscsi_iqn = utils.get_node_id_info(node_id)
fc_wwns = fc_wwns_str.split(servers_settings.PARAMETERS_FC_WWN_DELIMITER)
self.node_name = node_name
self.initiators = Initiators([nvme_nqn], fc_wwns, [iscsi_iqn])
self.node_name = node_id


@dataclass
class Initiators:
"""
Object containing node initiators (e.g. iqn, fc_wwns)
Usage:
inits = Initiators([nvme_nqn], fc_wwns, [iscsi_iqn])
"""
nvme_nqns: list = field(default_factory=list)
fc_wwns: list = field(default_factory=list)
Expand Down
3 changes: 0 additions & 3 deletions controllers/common/settings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from controllers.common.config import config

NAME_PREFIX_SEPARATOR = "_"
ENDPOINTS_SEPARATOR = ", "

Expand All @@ -11,7 +9,6 @@
ARRAY_TYPE_DS8K = 'DS8K'
ALL_ARRAY_TYPES = [ARRAY_TYPE_XIV, ARRAY_TYPE_SVC, ARRAY_TYPE_DS8K]

PARAMETERS_NODE_ID_DELIMITER = config.parameters.node_id_info.delimiter
SPACE_EFFICIENCY_THIN = "thin"
SPACE_EFFICIENCY_COMPRESSED = "compressed"
SPACE_EFFICIENCY_DEDUPLICATED = "deduplicated"
Expand Down
19 changes: 0 additions & 19 deletions controllers/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
import re
import urllib3

from controllers.common import settings
from controllers.common.csi_logger import get_stdout_logger
from controllers.servers import messages

logger = get_stdout_logger()

Expand Down Expand Up @@ -40,23 +38,6 @@ def string_to_array(str_val, separator):
return res


def get_node_id_info(node_id):
logger.debug("getting node info for node id : {0}".format(node_id))
split_node = node_id.split(settings.PARAMETERS_NODE_ID_DELIMITER)
hostname, nvme_nqn, fc_wwns, iscsi_iqn = "", "", "", ""
if len(split_node) == 4:
hostname, nvme_nqn, fc_wwns, iscsi_iqn = split_node
elif len(split_node) == 3:
hostname, nvme_nqn, fc_wwns = split_node
elif len(split_node) == 2:
hostname, nvme_nqn = split_node
else:
raise ValueError(messages.WRONG_FORMAT_MESSAGE.format("node id"))
logger.debug("node name : {0}, nvme_nqn: {1}, fc_wwns : {2}, iscsi_iqn : {3} ".format(
hostname, nvme_nqn, fc_wwns, iscsi_iqn))
return hostname, nvme_nqn, fc_wwns, iscsi_iqn


def _get_workers_limit_info():
return os.environ.get('WORKERS_LIMIT')

Expand Down
22 changes: 19 additions & 3 deletions controllers/servers/csi/csi_controller_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
from controllers.array_action.storage_agent import get_agent, detect_array_type
from controllers.common.config import config as common_config
from controllers.common.csi_logger import get_stdout_logger
from controllers.common.node_info import NodeIdInfo
from controllers.common.node_info import NodeIdInfo, Initiators
from controllers.servers import messages as controller_messages
from controllers.servers.csi.decorators import csi_method
from controllers.servers.csi.exception_handler import handle_exception, \
build_error_response
from controllers.servers.errors import ObjectIdError, ValidationException, InvalidNodeId
from controllers.servers.host_definer.kubernetes_manager.manager import KubernetesManager

logger = get_stdout_logger()

Expand Down Expand Up @@ -218,8 +219,17 @@ def DeleteVolume(self, request, context):

return csi_pb2.DeleteVolumeResponse()

def _get_node_initiators(self, node_id):
logger.info("debug - uriziv - 31")
kubernetes_manager = KubernetesManager()
k8s_node = kubernetes_manager.core_api.read_node(name=node_id)
ret_val = k8s_node.metadata.annotations
logger.info("debug - uriziv - 32")
return ret_val

@csi_method(error_response_type=csi_pb2.ControllerPublishVolumeResponse, lock_request_attribute="volume_id")
def ControllerPublishVolume(self, request, context):
logger.info("debug - uriziv - 25")
try:
utils.validate_publish_volume_request(request)

Expand All @@ -228,8 +238,12 @@ def ControllerPublishVolume(self, request, context):
array_type = volume_id_info.array_type
volume_id = volume_id_info.ids.uid
node_id_info = NodeIdInfo(request.node_id)
logger.info(request)
node_name = node_id_info.node_name
initiators = node_id_info.initiators
node_initiators = self._get_node_initiators(node_name)
logger.info("node_initiators: %s", node_initiators)
# TODO(uriziv1) - init Initiators object
initiators = Initiators(["iscsi"], ["fc1", "fc2", "fc3"], ["nvme"])

logger.debug("node name for this publish operation is : {0}".format(node_name))

Expand All @@ -248,6 +262,7 @@ def ControllerPublishVolume(self, request, context):
response = utils.generate_csi_publish_volume_response(lun,
connectivity_type,
array_initiators)
logger.info("debug - uriziv - 26")
return response

except array_errors.VolumeAlreadyMappedToDifferentHostsError as ex:
Expand All @@ -273,7 +288,8 @@ def ControllerUnpublishVolume(self, request, context):
volume_id = volume_id_info.ids.uid
node_id_info = NodeIdInfo(request.node_id)
node_name = node_id_info.node_name
initiators = node_id_info.initiators
# TODO(uriziv1) - get initiators from nodeid
initiators = Initiators(["iscsi"], ["fc1", "fc2", "fc3"], ["nvme"])
logger.debug("node name for this unpublish operation is : {0}".format(node_name))

array_connection_info = utils.get_array_connection_info_from_secrets(request.secrets,
Expand Down
1 change: 1 addition & 0 deletions controllers/servers/csi/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ munch==4.0.0
retry2==0.9.5
packaging==25.0
base58==2.1.1
kubernetes==33.1.0

# A9000 python client
pyxcli==1.2.1
Expand Down
2 changes: 2 additions & 0 deletions controllers/servers/host_definer/hd_types.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from dataclasses import dataclass, field
from controllers.servers.csi.controller_types import ArrayConnectionInfo
from controllers.servers.host_definer import utils
from controllers.common.node_info import Initiators


@dataclass
Expand All @@ -9,6 +10,7 @@ class DefineHostRequest:
connectivity_type_from_user: str = ''
node_id_from_host_definition: str = ''
node_id_from_csi_node: str = ''
node_initiators: Initiators = Initiators(nvme_nqns=[], fc_wwns=[], iscsi_iqns=[])
array_connection_info: ArrayConnectionInfo = ArrayConnectionInfo(array_addresses='', user='', password='',
partition_name='', partition_vg='', port_set='')
io_group: str = ''
Expand Down
10 changes: 10 additions & 0 deletions controllers/servers/host_definer/host_definer_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,28 @@ def __init__(self):

def start_host_definition(self):
logger.info('starting host definer')
logger.info("DEBUG - uriziv - 73")
self.csi_node_watcher.add_initial_csi_nodes()
logger.info("DEBUG - uriziv - 74")
self.storage_class_watcher.add_initial_storage_classes()
logger.info("DEBUG - uriziv - 75")
self.node_watcher.add_initial_nodes()
logger.info(self.csi_node_watcher.get_nodes_var())
logger.info(self.csi_node_watcher.get_managed_secrets_var())
logger.info(self.storage_class_watcher.get_nodes_var())
logger.info(self.storage_class_watcher.get_managed_secrets_var())
logger.info("DEBUG - uriziv - 76")
self._start_watchers()

def _start_watchers(self):
logger.info("DEBUG - uriziv - 17")
watchers = (
self.csi_node_watcher.watch_csi_nodes_resources,
self.host_definition_watcher.watch_host_definitions_resources,
self.secret_watcher.watch_secret_resources,
self.node_watcher.watch_nodes_resources,
self.storage_class_watcher.watch_storage_class_resources)
logger.info("DEBUG - uriziv - 18")
for watch_function in watchers:
thread = Thread(target=watch_function,)
thread.start()
47 changes: 47 additions & 0 deletions controllers/servers/host_definer/kubernetes_manager/manager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ast
import datetime
import base64
import json

from kubernetes import client, config, dynamic
from kubernetes.client import api_client
Expand All @@ -12,6 +13,8 @@
import controllers.common.settings as common_settings
from controllers.servers.host_definer.hd_types import (
CsiNodeInfo, PodInfo, NodeInfo, StorageClassInfo, HostDefinitionInfo)
from controllers.common.node_info import NodeIdInfo
from controllers.common.node_info import Initiators

logger = get_stdout_logger()

Expand All @@ -33,6 +36,33 @@ def _get_dynamic_client(self):
def _load_cluster_configuration(self):
return config.load_incluster_config()

def _get_node_ids_info(self):
try:
node_ids_info = []
for k8s_node in self.core_api.list_node().items:
k8s_node = self._generate_node_id_info(k8s_node)
node_ids_info.append(k8s_node)
return node_ids_info
except ApiException as ex:
logger.error(messages.FAILED_TO_GET_NODES.format(ex.body))
return []

def _get_node_id_info(self, node_name):
k8s_node = self._read_node(node_name)
logger.info("DEBUG - uriziv - 27")
if k8s_node:
return self._generate_node_id_info(k8s_node)
node_id_for_node_id_info_object = ';;;'
logger.info(node_id_for_node_id_info_object)
logger.info("DEBUG - uriziv - 28")
return NodeIdInfo(node_id_for_node_id_info_object)

def _generate_node_id_info(self, k8s_node):
logger.info("DEBUG - uriziv - 29")
node_id_for_node_id_info_object = f"{k8s_node.metadata.name};;;"
logger.info("DEBUG - uriziv - 30")
return NodeIdInfo(node_id_for_node_id_info_object)

def _get_csi_nodes_api(self):
return self.dynamic_client.resources.get(api_version=settings.STORAGE_API_VERSION,
kind=settings.CSINODE_KIND)
Expand Down Expand Up @@ -327,6 +357,12 @@ def _get_node_info(self, node_name):
return self._generate_node_info(k8s_node)
return NodeInfo('', {})

def _get_node_initiators(self, node_name):
k8s_node = self._read_node(node_name)
if k8s_node:
return self._generate_node_initiators(k8s_node)
return Initiators([], [], [])

def _read_node(self, node_name):
try:
logger.info(messages.READ_NODE.format(node_name))
Expand All @@ -338,6 +374,17 @@ def _read_node(self, node_name):
def _generate_node_info(self, k8s_node):
return NodeInfo(k8s_node.metadata.name, k8s_node.metadata.labels)

def _generate_node_initiators(self, k8s_node):
logger.info("DEBUG - uriziv - 71")
logger.info(k8s_node.metadata.annotations)
node_initiators_raw = k8s_node.metadata.annotations.get("block.csi.ibm.com/node-ports", "{}")
initiators_data = json.loads(node_initiators_raw)
nvme_nqns = initiators_data.get("nvme", [])
fc_wwns = initiators_data.get("fc", [])
iscsi_iqns = initiators_data.get("iscsi", [])
logger.info("DEBUG - uriziv - 72")
return Initiators(nvme_nqns, fc_wwns, iscsi_iqns)

def _get_csi_daemon_set(self):
try:
daemon_sets = self.apps_api.list_daemon_set_for_all_namespaces(label_selector=settings.DRIVER_PRODUCT_LABEL)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
"""host_definer_server.py"""
import json

from controllers.array_action import settings as array_config
from controllers.array_action.errors import HostNotFoundError, HostAlreadyExists
from controllers.array_action.storage_agent import detect_array_type, get_agent
from controllers.common.csi_logger import get_stdout_logger
from controllers.common.node_info import NodeIdInfo
from controllers.common.node_info import NodeIdInfo, Initiators
import controllers.common.settings as common_settings
from controllers.servers.host_definer.hd_types import DefineHostResponse
from controllers.servers.utils import join_object_prefix_with_name, get_initiators_connectivity_type
import controllers.servers.host_definer.settings as host_definer_settings
from controllers.servers.host_definer import messages
from controllers.servers.host_definer.kubernetes_manager.manager import KubernetesManager

logger = get_stdout_logger()


class HostDefinerServicer:
def define_host(self, request):
logger.info("DEBUG - uriziv - 7")
logger.info(type(request)) # DefineHostRequest
logger.info(request)
logger.info("DEBUG - uriziv - 8")
array_connection_info = request.array_connection_info
array_addresses = array_connection_info.array_addresses
node_id_info = NodeIdInfo(request.node_id_from_csi_node)
initiators = node_id_info.initiators
initiators = request.node_initiators
node_name = node_id_info.node_name
connectivity_type_from_user = get_initiators_connectivity_type(initiators, request.connectivity_type_from_user)
host_name = join_object_prefix_with_name(prefix=request.prefix, name=node_name)
Expand All @@ -28,6 +35,7 @@ def define_host(self, request):
try:
initiators_from_host_definition = self._get_initiators_from_node_id(
request.node_id_from_host_definition)
# TODO(uriziv12): consider: initiators_from_host_definition = request.node_initiators
found_host_name = self._get_host_name(initiators_from_host_definition, array_mediator)
# Partition update is first one - verifies partition can be fixed (may fail if mapped)
self._update_host_partition(request, found_host_name,
Expand Down Expand Up @@ -58,7 +66,8 @@ def undefine_host(self, request):
node_id_info = NodeIdInfo(request.node_id_from_csi_node)
array_connection_info = request.array_connection_info
array_addresses = array_connection_info.array_addresses
initiators = node_id_info.initiators
# TODO(uriziv1): get initiators
initiators = Initiators(["iscsi"], ["fc1", "fc2", "fc3"], ["nvme"])
node_name = node_id_info.node_name
logger.info(messages.UNDEFINE_NODE_FROM_ARRAYS.format(node_name, array_addresses))
try:
Expand Down Expand Up @@ -109,8 +118,17 @@ def _update_host_ports(self, request, host, array_mediator, partition_name):
raise ex

def _get_initiators_from_node_id(self, node_id):
node_id_info = NodeIdInfo(node_id)
return node_id_info.initiators
logger.info("DEBUG - uriziv - 43")
# node_id_info = NodeIdInfo(node_id)
kubernetes_manager = KubernetesManager()
k8s_node = kubernetes_manager.core_api.read_node(name=node_id)
node_initiators_raw = k8s_node.metadata.annotations.get("block.csi.ibm.com/node-ports", "{}")
initiators_data = json.loads(node_initiators_raw)
nvme_nqns = initiators_data.get("nvme", [])
fc_wwns = initiators_data.get("fc", [])
iscsi_iqns = initiators_data.get("iscsi", [])
logger.info("DEBUG - uriziv - 44")
return Initiators(nvme_nqns, fc_wwns, iscsi_iqns)

def _is_protocol_switched(self, connectivity_type_from_user, connectivity_type_from_host):
return self._is_switching_from_nvme_to_scsi(connectivity_type_from_user, connectivity_type_from_host) or \
Expand Down
2 changes: 2 additions & 0 deletions controllers/servers/host_definer/watcher/csi_node_watcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
class CsiNodeWatcher(Watcher):

def add_initial_csi_nodes(self):
logger.info("DEBUG - uriziv - 77")
csi_nodes_info = self._get_csi_nodes_info_with_driver()
for csi_node_info in csi_nodes_info:
if self._is_host_can_be_defined(csi_node_info.name):
self._add_node_to_nodes(csi_node_info)
logger.info("DEBUG - uriziv - 78")

def watch_csi_nodes_resources(self):
while self._loop_forever():
Expand Down
Loading