
On previous installations, the subcloud kube-rootca certificate is different than the one from system controller. Currently, the audit is comparing cert_id and declaring out-of-sync if they don't match, which leads to an out-of-sync in the endpoint post upgrade. This commit changes the audit logic to first audit by alarms so upgraded subclouds can remain in-sync. Audit by cert_id still happen, but only if the subcloud was rehomed. Additionally, the force parameter was re-introduced in kube-rootca update orchestration. Since with alarm based audit different cert_ids can still present an in-sync status, the user might want to update subcloud cert to match system controller, so the force parameter is necessary to allow this. Note: Dcagent didn't previously allowed extra_args to be sent in in the payload. To avoid breaking audit with previous versions of dcagent sending an unknown key in the payload (which will thrown an error), extra_args are being sent in request header with the key "X-DCAGENT-HEADERS". Support for extra_args in the payload was added, but can only be used when all supported dcagent versions have this option. Note: Due to the current issue that blocks upgrade test, this commit did not test subcloud upgrade, but the scenario would follow a similar path from the second test case below, where updating a subcloud rootca to a different cert from system controller results in an in-sync endpoint status. Test plan: - PASS: Deploy a subcloud and verify kube-rootca_sync_status is in-sync. - PASS: Perform a kube-rootca update orchestration directly in the subcloud without passing a cert so it will auto generate one and verify kube-rootca_sync_status is still in-sync. - PASS: Rehome the subcloud from the previous test and verify kube-rootca_sync_status is out-of-sync. - PASS: Perform a kube-rootca update orchestration using dcmanager in an out-of-sync subcloud providing system controller certs and verify the final sync status is in-sync. - PASS: Perform a kube-rootca update orchestration using dcmanager in an in-sync subcloud with force parameter without providing certs and verify the final sync status is in-sync. - PASS: Install a N-1 release and verify kube-rootca_sync_status is in-sync. Closes-bug: 2092069 Change-Id: If0cc002d0d4970730771ae90d80dc50c7daf4d4c Signed-off-by: Victor Romano <victor.gluzromano@windriver.com>
78 lines
2.6 KiB
Python
78 lines
2.6 KiB
Python
#
|
|
# Copyright (c) 2024 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
|
|
import http.client
|
|
import json
|
|
|
|
from oslo_config import cfg
|
|
from oslo_log import log as logging
|
|
import pecan
|
|
from pecan import expose
|
|
from pecan import request
|
|
|
|
from dcagent.api.controllers import restcomm
|
|
from dcagent.common.audit_manager import RequestedAudit
|
|
from dcagent.common.exceptions import UnsupportedAudit
|
|
from dcagent.common.i18n import _
|
|
|
|
CONF = cfg.CONF
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class AuditController(object):
|
|
@expose(generic=True, template="json")
|
|
def index(self):
|
|
# Route the request to specific methods with parameters
|
|
pass
|
|
|
|
@index.when(method="PATCH", template="json")
|
|
def patch(self):
|
|
"""Return the audit information."""
|
|
|
|
context = restcomm.extract_context_from_environ()
|
|
|
|
# Convert JSON string in request to Python dict
|
|
try:
|
|
payload = json.loads(request.body)
|
|
except ValueError:
|
|
pecan.abort(http.client.BAD_REQUEST, _("Request body decoding error"))
|
|
|
|
if not payload:
|
|
pecan.abort(http.client.BAD_REQUEST, _("Body required"))
|
|
|
|
# TODO(vgluzrom): Remove extra_args from header and keep it only in payload
|
|
# once all supported dcagent versions have this possibility. If system
|
|
# controller sends extra_args in payload to a dcagent that doesn't support it,
|
|
# it will raise an UnsupportedAudit exception.
|
|
try:
|
|
headers = json.loads(request.headers.get("X-DCAGENT-HEADERS", "{}"))
|
|
except ValueError:
|
|
pecan.abort(http.client.BAD_REQUEST, _("Request headers decoding error"))
|
|
|
|
extra_args = payload.pop("extra_args", {})
|
|
extra_args = {**extra_args, **headers}
|
|
|
|
LOG.debug(
|
|
f"Payload sent by system controller: {payload}. Extra args: {extra_args}"
|
|
)
|
|
|
|
try:
|
|
# Delete "use_cache" from payload so it doesn't get passed as an audit
|
|
use_cache = payload.pop("use_cache", True)
|
|
# request_token is used for calls not involving cache
|
|
requested_audit = RequestedAudit(
|
|
request_token=context.auth_token, use_cache=use_cache
|
|
)
|
|
return requested_audit.get_sync_status(payload, extra_args)
|
|
|
|
except UnsupportedAudit as ex:
|
|
LOG.exception(ex)
|
|
pecan.abort(http.client.BAD_REQUEST, ex.msg)
|
|
except Exception as ex:
|
|
LOG.exception(ex)
|
|
msg = f"Unable to get audit info: {ex}"
|
|
pecan.abort(http.client.INTERNAL_SERVER_ERROR, _(msg))
|