sw-manager fails with SSL and CA Cert provided.

When sw-manager is used through a secure connection (https
enabled) either with the remote CLI or within the cluster
via the public interface, the operation fails if the
Certificate Authority's cert is not included among the
system's trusted CAs.

The sw-manager client lacks implemented methods for
referencing a local Certificate Authority Cert during calls.
Therefore, if the CA is not among the system's trusted CAs,
all calls made by sw-manager's CLI will fail since
authentication in Keystone will also fail.

Other CLIs like fm or platform allow referencing a CA Cert
via the "REQUESTS_CA_BUNDLE" environment variable. The fix
involves loading, if defined, the CA Cert referenced by
such an environment variable, and adjusting SSL calls to
verify connections using the provided CA Cert.

Test Plan:
  PASS Fresh Install SX Env

  PASS Source openrc.sh file (internal interface).
  PASS sw-manager patch-strategy show

  PASS Enable secure mode (https)
  PASS Download OpenStack RC File from Horizon.
  PASS Source RC file inside cluster (public interface).
  PASS Set REQUESTS_CA_BUNDLE with CA-Cert path.
  PASS sw-manager patch-strategy show

  PASS Enable secure mode (https)
  PASS Download OpenStack RC File from Horizon.
  PASS Install remote CLI (custom container with changes)
  PASS Source downloaded RC file
  PASS Set REQUESTS_CA_BUNDLE with CA-Cert path.
  PASS sw-manager patch-strategy show

Closes-bug: 2033561

Change-Id: If5b70714cde09bd8c329b976a8148daee9001415
Signed-off-by: Jorge Saffe <jorge.saffe@windriver.com>
This commit is contained in:
Jorge Saffe 2023-08-25 17:21:02 -04:00
parent 6dba3df3e3
commit 9feef4232d
2 changed files with 11 additions and 5 deletions

View File

@ -1,9 +1,10 @@
# #
# Copyright (c) 2016-2022 Wind River Systems, Inc. # Copyright (c) 2016-2023 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
import json import json
import os
from six.moves import urllib from six.moves import urllib
from nfv_client.openstack.objects import Token from nfv_client.openstack.objects import Token
@ -25,6 +26,7 @@ class OpenStackServiceTypes(object):
SERVICE = OpenStackServices() SERVICE = OpenStackServices()
SERVICE_TYPE = OpenStackServiceTypes() SERVICE_TYPE = OpenStackServiceTypes()
CAFILE = os.environ.get('REQUESTS_CA_BUNDLE')
def get_token(auth_uri, project_name, project_domain_name, username, password, def get_token(auth_uri, project_name, project_domain_name, username, password,
@ -34,7 +36,7 @@ def get_token(auth_uri, project_name, project_domain_name, username, password,
""" """
try: try:
# handle auth_uri re-direct (300) # handle auth_uri re-direct (300)
urllib.request.urlopen(auth_uri) urllib.request.urlopen(auth_uri, cafile=CAFILE)
except urllib.error.HTTPError as e: except urllib.error.HTTPError as e:
if e.code == 300: if e.code == 300:
auth_uri = e.headers['location'] auth_uri = e.headers['location']
@ -70,7 +72,7 @@ def get_token(auth_uri, project_name, project_domain_name, username, password,
request_info.data = payload.encode() request_info.data = payload.encode()
request = urllib.request.urlopen(request_info, timeout=30) request = urllib.request.urlopen(request_info, timeout=30, cafile=CAFILE)
# Identity API v3 returns token id in X-Subject-Token # Identity API v3 returns token id in X-Subject-Token
# response header. # response header.
token_id = request.headers.get('X-Subject-Token') token_id = request.headers.get('X-Subject-Token')

View File

@ -1,12 +1,15 @@
# #
# Copyright (c) 2016-2022 Wind River Systems, Inc. # Copyright (c) 2016-2023 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
import json import json
import os
from six.moves import http_client as httplib from six.moves import http_client as httplib
from six.moves import urllib from six.moves import urllib
CAFILE = os.environ.get('REQUESTS_CA_BUNDLE')
def request(token_id, method, api_cmd, api_cmd_headers=None, def request(token_id, method, api_cmd, api_cmd_headers=None,
api_cmd_payload=None, timeout_in_secs=40): api_cmd_payload=None, timeout_in_secs=40):
@ -35,7 +38,8 @@ def request(token_id, method, api_cmd, api_cmd_headers=None,
request_info.data = api_cmd_payload.encode() request_info.data = api_cmd_payload.encode()
url_request = urllib.request.urlopen(request_info, url_request = urllib.request.urlopen(request_info,
timeout=timeout_in_secs) timeout=timeout_in_secs,
cafile=CAFILE)
headers = list() # list of tuples headers = list() # list of tuples
for key, value in url_request.info().items(): for key, value in url_request.info().items():