Use mgmt_ipsec in sysinv for ipsec request check

Currently ipsec server use inv_state in sysinv to check the validation
of the auth request from client. This is found to be problematic. This
change updated ipsec server to use "mgmt_ipsec:enabling|enabled" flag
in capabilities of the i_host table for the validation checking.

Also a minor refactoring to move the flag setting into a function in
the utils module, since the flag setting will be eventually used in
multiple places.

Test Plan:
PASS: DX deployment in VBox. Verify controller-0 and controller-1
      are installed, bootstrap and unlocked successfully with IPSec
      configured and enabled.

Story: 2010940
Task: 49558

Change-Id: I397ea29d73ad8a3b8b8ce5500a4501c7bc2fbfbc
Signed-off-by: Andy Ning <andy.ning@windriver.com>
This commit is contained in:
Andy Ning 2024-02-09 11:47:52 -05:00
parent ae29b180c2
commit a79dae2db6
5 changed files with 63 additions and 29 deletions

View File

@ -1180,7 +1180,7 @@ class HostController(rest.RestController):
'downgrade': ['POST'],
'install_progress': ['POST'],
'wipe_osds': ['GET'],
'update_inv_state': ['POST'],
'update_mgmt_ipsec_state': ['POST'],
'mgmt_ip': ['GET'],
'kube_upgrade_control_plane': ['POST'],
'kube_upgrade_kubelet': ['POST'],
@ -1199,9 +1199,19 @@ class HostController(rest.RestController):
# self._name = 'api-host'
@wsme_pecan.wsexpose(six.text_type, wtypes.text, body=six.text_type)
def update_inv_state(self, uuid, data):
def update_mgmt_ipsec_state(self, uuid, data):
# Ensure data has valid value
if data not in [constants.MGMT_IPSEC_ENABLING, constants.MGMT_IPSEC_ENABLED]:
LOG.error(_("Invalid value for mgmt_ipsec: %s" % data))
return False
try:
pecan.request.dbapi.ihost_update(uuid, {'inv_state': data})
host = objects.host.get_by_uuid(pecan.request.context,
uuid)
if host:
capabilities = host.get('capabilities')
capabilities.update({'mgmt_ipsec': data})
pecan.request.dbapi.ihost_update(uuid, {'capabilities': capabilities})
except exception.ServerNotFound:
LOG.error(_('Failed to retrieve host with specified uuid.'))
return False

View File

@ -2465,3 +2465,7 @@ RUNTIME_CONFIG_STATE_RETRIED = "retried"
# LUKS vault type
LUKS_VAULT_TYPE_NAME = "luks_encrypted_vault"
# mgmt. network IPSec state
MGMT_IPSEC_ENABLING = 'enabling'
MGMT_IPSEC_ENABLED = 'enabled'

View File

@ -64,5 +64,5 @@ OP_CODE_PATCHING = 3
SUPPORTED_OP_CODES = [OP_CODE_INITIAL_AUTH,
OP_CODE_CERT_RENEWAL]
INV_STATE_INVENTORYING = 'inventorying'
INV_STATE_INVENTORIED = 'inventoried'
MGMT_IPSEC_ENABLING = 'enabling'
MGMT_IPSEC_ENABLED = 'enabled'

View File

@ -147,6 +147,23 @@ def get_client_hostname_and_mgmt_subnet(mac_addr):
return response
def update_host_mgmt_ipsec_state(uuid, state):
token = rest_api.get_token(constants.REGION_NAME)
sysinv_ihost_url = constants.PXECONTROLLER_URL + '/v1/ihosts/'
api_cmd = sysinv_ihost_url + uuid + '/update_mgmt_ipsec_state'
api_cmd_payload = '"{}"'.format(state)
api_cmd_headers = dict()
api_cmd_headers['Content-type'] = "application/json"
api_cmd_headers['User-Agent'] = "sysinv/1.0"
if not rest_api.rest_api_request(token, "POST", api_cmd,
api_cmd_headers=api_cmd_headers,
api_cmd_payload=api_cmd_payload):
return False
return True
def load_data(path):
data = None
with open(path, 'rb') as f:

View File

@ -227,37 +227,40 @@ class IPsecConnection(object):
return False
uuid = None
inv_state = None
mgmt_ipsec = None
mgmt_mac = None
personality = None
for h in hosts_info['ihosts']:
if message["mac_addr"] == h['mgmt_mac']:
uuid = h['uuid']
inv_state = h['inv_state']
mgmt_mac = h['mgmt_mac']
personality = h['personality']
if message["mac_addr"] == h.get('mgmt_mac'):
uuid = h.get('uuid')
mgmt_mac = h.get('mgmt_mac')
personality = h.get('personality')
capabilities = h.get('capabilities')
mgmt_ipsec = capabilities.get('mgmt_ipsec') if capabilities else None
break
if not uuid or not mgmt_mac or not personality or \
op_code == constants.OP_CODE_INITIAL_AUTH and inv_state != '' or \
op_code == constants.OP_CODE_CERT_RENEWAL and \
inv_state != constants.INV_STATE_INVENTORIED:
LOG.error("Invalid host information.")
return False
LOG.info("Request op:{}, host uuid:{}, mgmt_mac:{}, personality:{}, mgmt_ipsec:{}"
.format(op_code, uuid, mgmt_mac, personality, mgmt_ipsec))
if op_code == constants.OP_CODE_INITIAL_AUTH and inv_state == '':
api_cmd = sysinv_ihost_url + uuid + '/update_inv_state'
api_cmd_payload = '"{}"'.format(constants.INV_STATE_INVENTORYING)
api_cmd_headers = dict()
api_cmd_headers['Content-type'] = "application/json"
api_cmd_headers['User-Agent'] = "sysinv/1.0"
if not rest_api.rest_api_request(token, "POST", api_cmd,
api_cmd_headers=api_cmd_headers,
api_cmd_payload=api_cmd_payload):
LOG.error("Failed to update host inventory state.")
# Initial auth request
if op_code == constants.OP_CODE_INITIAL_AUTH:
if uuid and mgmt_mac and mgmt_ipsec is None:
if not utils.update_host_mgmt_ipsec_state(uuid,
constants.MGMT_IPSEC_ENABLING):
LOG.error("Failed to update host mgmt IPSec state.")
return False
else:
LOG.error("Invalid request for operation: %s" % op_code)
return False
# Certificate renewal request
elif op_code == constants.OP_CODE_CERT_RENEWAL:
if uuid and mgmt_mac and mgmt_ipsec == constants.MGMT_IPSEC_ENABLED:
# Valid so do nothing
pass
else:
LOG.error("Invalid request for operation: %s" % op_code)
return False
return True
def _generate_tmp_key_pair(self):