update/software/software/dc_utils.py

119 lines
3.6 KiB
Python

"""
Copyright (c) 2024 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
"""
import json
import logging
from keystoneauth1 import exceptions
from keystoneauth1 import identity
from keystoneauth1 import session
from oslo_config import cfg
from oslo_utils import encodeutils
from six.moves.urllib.request import Request
from six.moves.urllib.request import urlopen
from software import utils
from software.constants import SYSTEM_CONTROLLER_REGION
LOG = logging.getLogger('main_logger')
CONF = cfg.CONF
def get_token_endpoint(service_type, region_name=None, interface="internal"):
config = CONF.get('keystone_authtoken')
if region_name is None:
region_name = config.region_name
try:
auth = identity.Password(
auth_url=config.auth_url,
username=config.username,
password=config.password,
project_name=config.project_name,
user_domain_name=config.user_domain_name,
project_domain_name=config.project_domain_name
)
sess = session.Session(auth=auth)
token = sess.get_token()
endpoint = sess.get_endpoint(service_type=service_type,
region_name=region_name,
interface=interface)
except exceptions.http.Unauthorized:
raise Exception("Failed to authenticate to Keystone. Request unauthorized")
except Exception as e:
msg = "Failed to get token and endpoint. Error: %s", str(e)
raise Exception(msg)
return token, endpoint
def rest_api_request(token, method, api_cmd,
api_cmd_payload=None, timeout=45):
"""
Make a rest-api request
Returns: response as a dictionary
"""
api_cmd_headers = dict()
api_cmd_headers['Content-type'] = "application/json"
api_cmd_headers['User-Agent'] = "usm/1.0"
request_info = Request(api_cmd)
request_info.get_method = lambda: method
if token:
request_info.add_header("X-Auth-Token", token)
request_info.add_header("Accept", "application/json")
if api_cmd_headers is not None:
for header_type, header_value in api_cmd_headers.items():
request_info.add_header(header_type, header_value)
if api_cmd_payload is not None:
request_info.data = encodeutils.safe_encode(api_cmd_payload)
request = None
try:
request = urlopen(request_info, timeout=timeout)
response = request.read()
finally:
if request:
request.close()
if response == "":
response = json.loads("{}")
else:
response = json.loads(response)
return response
def get_subclouds_from_dcmanager():
token, api_url = get_token_endpoint("dcmanager", region_name=SYSTEM_CONTROLLER_REGION)
api_cmd = api_url + '/subclouds'
LOG.debug('api_cmd %s' % api_cmd)
data = rest_api_request(token, "GET", api_cmd)
if 'subclouds' in data:
return data['subclouds']
raise Exception(f"Incorrect response from dcmanager for querying subclouds {data}")
def get_subcloud_groupby_version():
subclouds = get_subclouds_from_dcmanager()
grouped_subclouds = {}
for subcloud in subclouds:
major_ver = utils.get_major_release_version(subcloud['software_version'])
if major_ver not in grouped_subclouds:
grouped_subclouds[major_ver] = [subcloud]
else:
grouped_subclouds[major_ver].append(subcloud)
msg = "total %s subclouds." % len(subclouds)
for ver in grouped_subclouds:
msg = msg + " %s: %s subclouds." % (ver, len(grouped_subclouds[ver]))
LOG.info(msg)
return grouped_subclouds