Merge "Adjust IPsec related codes to support upgrade"

This commit is contained in:
Zuul 2024-05-15 20:43:23 +00:00 committed by Gerrit Code Review
commit 69bb208f9e
5 changed files with 107 additions and 12 deletions

View File

@ -0,0 +1,83 @@
#!/usr/bin/python
# Copyright (c) 2024 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# This script is to update the "mgmt_ipsec" flag in capabilities of
# sysinv i_host table to "upgrading". This flag will be checked by
# ipsec-server when it receives IPsec config request from ipsec-client.
# It will refuse the request if this flag is "upgrading", meaning
# during upgrade, IPsec won't be configured/enabled.
import json
import sys
from psycopg2.extras import RealDictCursor
import psycopg2
from controllerconfig.common import log
from sysinv.common import constants
LOG = log.get_logger(__name__)
def main():
action = None
from_release = None
to_release = None # noqa
arg = 1
while arg < len(sys.argv):
if arg == 1:
from_release = sys.argv[arg]
elif arg == 2:
to_release = sys.argv[arg] # noqa
elif arg == 3:
action = sys.argv[arg]
else:
print(f"Invalid option {sys.argv[arg]}.")
return 1
arg += 1
log.configure()
if from_release == "22.12" and action == "migrate":
try:
LOG.info("Update mgmt_ipsec in capabilities of "
"sysinv i_host table,"
f"from the release {from_release} to {to_release} with "
f"action: {action}")
update_mgmt_ipsec(constants.MGMT_IPSEC_UPGRADING)
except Exception as ex:
LOG.exception(ex)
print(ex)
return 1
def update_mgmt_ipsec(value):
"""This function update mgmt_ipsec in in capabilities of sysinv
i_host table to the value.
"""
conn = psycopg2.connect("dbname='sysinv' user='postgres'")
with conn:
with conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute("select uuid, capabilities from i_host;")
rows = cur.fetchall()
if rows is None:
LOG.exception("Failed to fetch i_host data")
raise
for record in rows:
capabilities = json.loads(record['capabilities'])
capabilities.update({constants.MGMT_IPSEC_FLAG: value})
sqlcom = ("update i_host set "
f"capabilities='{json.dumps(capabilities)}' "
f"where uuid='{record['uuid']}'")
cur.execute(sqlcom)
conn.commit()
if __name__ == "__main__":
sys.exit(main())

View File

@ -1208,7 +1208,7 @@ class HostController(rest.RestController):
# Ensure data has valid value
if data not in [constants.MGMT_IPSEC_ENABLING,
constants.MGMT_IPSEC_ENABLED, constants.MGMT_IPSEC_DISABLED]:
LOG.error(_("Invalid value for mgmt_ipsec: %s" % data))
LOG.error(_("Invalid value for %s: %s" % (constants.MGMT_IPSEC_FLAG, data)))
return False
try:
@ -1218,10 +1218,10 @@ class HostController(rest.RestController):
capabilities = host.get('capabilities')
if (data == constants.MGMT_IPSEC_DISABLED and
capabilities.get('mgmt_ipsec') is not None):
capabilities.pop('mgmt_ipsec')
capabilities.get(constants.MGMT_IPSEC_FLAG) is not None):
capabilities.pop(constants.MGMT_IPSEC_FLAG)
else:
capabilities.update({'mgmt_ipsec': data})
capabilities.update({constants.MGMT_IPSEC_FLAG: data})
pecan.request.dbapi.ihost_update(uuid, {'capabilities': capabilities})
except exception.ServerNotFound:
@ -7021,8 +7021,8 @@ class HostController(rest.RestController):
# Remove IPSec flag to allow a new configuration after reinstall
capabilities = hostupdate.ihost_orig['capabilities']
if capabilities.get('mgmt_ipsec') is not None:
capabilities.pop('mgmt_ipsec')
if capabilities.get(constants.MGMT_IPSEC_FLAG) is not None:
capabilities.pop(constants.MGMT_IPSEC_FLAG)
hostupdate.ihost_val_update({'capabilities': capabilities})
hostupdate.notify_mtce = True

View File

@ -2511,10 +2511,14 @@ RUNTIME_CONFIG_STATE_RETRIED = "retried"
# LUKS vault type
LUKS_VAULT_TYPE_NAME = "luks_encrypted_vault"
# mgmt. network IPsec flag
MGMT_IPSEC_FLAG = 'mgmt_ipsec'
# mgmt. network IPSec state
MGMT_IPSEC_ENABLING = 'enabling'
MGMT_IPSEC_ENABLED = 'enabled'
MGMT_IPSEC_DISABLED = 'disabled'
MGMT_IPSEC_UPGRADING = 'upgrading'
# If True, makes outputs compatible with single stack versions of ansible-playbooks and stx-puppet.
# Shall be removed when the other projects are updated.

View File

@ -66,6 +66,7 @@ SUPPORTED_OP_CODES = [OP_CODE_INITIAL_AUTH,
MGMT_IPSEC_ENABLING = 'enabling'
MGMT_IPSEC_ENABLED = 'enabled'
MGMT_IPSEC_DISABLED = 'disabled'
MGMT_IPSEC_UPGRADING = 'upgrading'
CHILD_SA_NAME = 'node'
IKE_SA_NAME = 'system-nodes'

View File

@ -299,9 +299,10 @@ class IPsecConnection(object):
self.ots_token.purge()
if (self.op_code == constants.OP_CODE_INITIAL_AUTH and
self.mgmt_ipsec != constants.MGMT_IPSEC_ENABLED and not
self._update_mgmt_ipsec_state(constants.MGMT_IPSEC_DISABLED)):
return False
self.mgmt_ipsec and
self.mgmt_ipsec != constants.MGMT_IPSEC_ENABLED and
self.mgmt_ipsec != constants.MGMT_IPSEC_UPGRADING):
return self._update_mgmt_ipsec_state(constants.MGMT_IPSEC_DISABLED)
return True
@ -340,10 +341,16 @@ class IPsecConnection(object):
LOG.error("TLS secret is unreachable.")
return
data = bytes(secret.data.get(attr, None), "utf-8")
if not data:
data = secret.data.get(attr, None)
if data is None:
if attr == self.ROOT_CA_CRT:
data = secret.data.get(self.CA_CRT, None)
if data is None:
LOG.error("Failed to retrieve %s info." % attr)
return
return data
data = bytes(data, "utf-8")
if attr == self.CA_KEY:
data = base64.b64decode(data)