add vmware-tools
This commit is contained in:
@@ -0,0 +1,607 @@
|
||||
# Copyright (c) 2024-2025 Broadcom. All Rights Reserved.
|
||||
# The term "Broadcom" refers to Broadcom Inc.
|
||||
# and/or its subsidiaries.
|
||||
|
||||
import ldap3 as ldap
|
||||
import logging
|
||||
import re
|
||||
from lib import certificate_utils as certutil
|
||||
from lib.environment import Environment
|
||||
from lib.certificate_utils import build_pem_certificate
|
||||
from lib.command_runner import CommandRunner
|
||||
from lib.console import print_task, print_text_error
|
||||
from lib.host_utils import VcVersion, get_hostname, get_vc_version
|
||||
from lib.ldap_utils import Ldap, LdapException, get_user_dn
|
||||
from lib.text_utils import TextFilter
|
||||
from lib.console import (print_task_status)
|
||||
from lib.exceptions import OperationFailed, CommandExecutionError
|
||||
|
||||
|
||||
DIR_CLI = '/usr/lib/vmware-vmafd/bin/dir-cli'
|
||||
VDCADMINTOOL = '/usr/lib/vmware-vmdir/bin/vdcadmintool'
|
||||
cache_ca_keyids = None
|
||||
cache_ca_certificate_map = dict()
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_ldap_connection(use_machine_account=False):
|
||||
env = Environment.get_environment()
|
||||
if use_machine_account:
|
||||
user_dn = env.get_value('VMDIR_MACHINE_ACCOUNT_DN')
|
||||
user_password = env.get_value('VMDIR_MACHINE_ACCOUNT_PASSWORD')
|
||||
else:
|
||||
sso_username = env.get_value('SSO_USERNAME')
|
||||
user_password = env.get_value('SSO_PASSWORD')
|
||||
user_dn = get_user_dn(sso_username)
|
||||
hostname = get_hostname()
|
||||
|
||||
return Ldap.open_ldap_connection(node=hostname, user_dn=user_dn, password=user_password)
|
||||
|
||||
|
||||
def close_ldap_connection(ldap_connection):
|
||||
Ldap.close_ldap_connection(ldap_connection)
|
||||
|
||||
|
||||
def perform_ldap_search(search_base, search_filter, search_attributes, search_scope=ldap.SUBTREE,
|
||||
use_machine_account=False, throw_exception=False):
|
||||
"""
|
||||
Utility method to perform LDAP search
|
||||
|
||||
:param search_base: LDAP search base DN
|
||||
:param search_filter: LDAP search filter
|
||||
:param search_attributes: LDAP search attribute
|
||||
:param search_scope: LDAP search scope (default: ldap.SUBTREE)
|
||||
:param use_machine_account: Flag to use VMDir machine account instead of SSO user account
|
||||
:param throw_exception: When LDAP search fails, throw exception instead of empty result
|
||||
:return: list of matching object, as dict with keys from search_attributes paramerter
|
||||
"""
|
||||
results = []
|
||||
connection = None
|
||||
try:
|
||||
connection = get_ldap_connection(use_machine_account)
|
||||
if not Ldap.ldap_search(connection, search_base, search_filter, search_scope, search_attributes):
|
||||
logger.error("Unable to perform LDAP search base_dn={}, filter={}" \
|
||||
.format(search_base, search_filter))
|
||||
if throw_exception:
|
||||
raise LdapException(connection.result['result'], connection.result['description'])
|
||||
else:
|
||||
return results
|
||||
if connection.result:
|
||||
for entry in connection.response:
|
||||
attributes = entry['attributes']
|
||||
if 'dn' in search_attributes and not attributes['dn']:
|
||||
attributes['dn'] = entry['dn'].replace(', cn=', ',cn=')
|
||||
results.append(attributes)
|
||||
finally:
|
||||
if connection:
|
||||
close_ldap_connection(connection)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def perform_ldap_add(service_dn, object_class, attributes, use_machine_account=False):
|
||||
"""
|
||||
A wrapper for LDAP modify operation
|
||||
"""
|
||||
connection = None
|
||||
try:
|
||||
connection = get_ldap_connection(use_machine_account)
|
||||
if not Ldap.ldap_add(connection, service_dn, object_class, attributes):
|
||||
logger.error("Unable to add LDAP entry dn={}, attributes={}".format(service_dn, str(attributes)))
|
||||
raise LdapException(connection.result['result'], connection.result['description'])
|
||||
finally:
|
||||
if connection:
|
||||
close_ldap_connection(connection)
|
||||
|
||||
|
||||
def perform_ldap_modify(service_dn, attribute, value, operation=ldap.MODIFY_REPLACE,
|
||||
use_machine_account=False):
|
||||
"""
|
||||
A wrapper for LDAP modify operation
|
||||
"""
|
||||
connection = None
|
||||
try:
|
||||
connection = get_ldap_connection(use_machine_account)
|
||||
if not Ldap.ldap_modify(connection, service_dn, attribute, operation, value):
|
||||
logger.error("Unable to modify LDAP entry dn={}, attribute={}".format(service_dn, attribute))
|
||||
raise LdapException(connection.result['result'], connection.result['description'])
|
||||
finally:
|
||||
if connection:
|
||||
close_ldap_connection(connection)
|
||||
|
||||
|
||||
def perform_ldap_delete(service_dn, use_machine_account=False):
|
||||
"""
|
||||
A wrapper for LDAP delete operation
|
||||
"""
|
||||
connection = None
|
||||
try:
|
||||
connection = get_ldap_connection(use_machine_account)
|
||||
if not Ldap.ldap_delete(connection, service_dn):
|
||||
logger.error("Unable to delete LDAP entry dn={}".format(service_dn))
|
||||
raise LdapException(connection.result['result'], connection.result['description'])
|
||||
finally:
|
||||
if connection:
|
||||
close_ldap_connection(connection)
|
||||
|
||||
|
||||
def get_solution_users():
|
||||
"""
|
||||
Get solution users list from VMDir via LDAP
|
||||
|
||||
:return: list of solution users
|
||||
"""
|
||||
env = Environment.get_environment()
|
||||
machine_id = env.get_value('MACHINE_ID')
|
||||
domain_dn = env.get_value('SSO_DOMAIN_DN')
|
||||
|
||||
postfix = "-{}".format(machine_id)
|
||||
search_base = "cn=ServicePrincipals,{}".format(domain_dn)
|
||||
search_filter = "(&(objectClass=vmwServicePrincipal)(cn=*{}))".format(postfix)
|
||||
search_attributes = ['cn']
|
||||
results = perform_ldap_search(search_base, search_filter, search_attributes)
|
||||
return [entry['cn'].replace(postfix, '') for entry in results]
|
||||
|
||||
|
||||
def get_sts_tenant_certificates(include_tenant_credential=True,
|
||||
include_certificate_chain=True):
|
||||
"""
|
||||
Get STS tenant user certificates
|
||||
:return: dict(cn: certificate list)
|
||||
"""
|
||||
env = Environment.get_environment()
|
||||
sso_domain = env.get_value('SSO_DOMAIN')
|
||||
domain_dn = env.get_value('SSO_DOMAIN_DN')
|
||||
|
||||
base_dn = "cn={},cn=Tenants,cn=IdentityManager,cn=Services,{}".format(sso_domain, domain_dn)
|
||||
if include_certificate_chain and include_tenant_credential:
|
||||
ldap_filter = \
|
||||
'(|(objectClass=vmwSTSTenantCredential)(&(objectclass=vmwSTSTenantTrustedCertificateChain)(cn=TrustedCertChain*)))'
|
||||
elif include_tenant_credential:
|
||||
ldap_filter = '(objectClass=vmwSTSTenantCredential)'
|
||||
elif include_certificate_chain:
|
||||
ldap_filter = '(&(objectclass=vmwSTSTenantTrustedCertificateChain)(cn=TrustedCertChain*))'
|
||||
else:
|
||||
return None
|
||||
|
||||
ldap_attributes = ['cn', 'userCertificate']
|
||||
results = perform_ldap_search(base_dn, ldap_filter, ldap_attributes)
|
||||
|
||||
tenant_certs = dict()
|
||||
for entry in results:
|
||||
tenant_certs[entry['cn']] = [build_pem_certificate(cert) for cert in entry['userCertificate']]
|
||||
|
||||
return tenant_certs
|
||||
|
||||
|
||||
def get_solution_user_certificate(solution_user):
|
||||
"""
|
||||
Get solution user certificate from VMDir via LDAP
|
||||
|
||||
:param solution_user: solution user
|
||||
:return: Solution user certificate in PEM format
|
||||
"""
|
||||
env = Environment.get_environment()
|
||||
machine_id = env.get_value('MACHINE_ID')
|
||||
domain_dn = env.get_value('SSO_DOMAIN_DN')
|
||||
|
||||
base_dn = "cn={}-{},cn=ServicePrincipals,{}".format(solution_user, machine_id, domain_dn)
|
||||
ldap_filter = '(objectClass=vmwServicePrincipal)'
|
||||
ldap_attributes = ['userCertificate']
|
||||
results = perform_ldap_search(base_dn, ldap_filter, ldap_attributes, search_scope=ldap.BASE)
|
||||
certs = []
|
||||
for entry in results:
|
||||
for cert in entry['userCertificate']:
|
||||
# only expect single certificate
|
||||
certs.append(build_pem_certificate(cert))
|
||||
return '\n'.join(certs)
|
||||
|
||||
|
||||
def get_all_ca_subject_keyids(use_cache=False):
|
||||
"""
|
||||
Get list of subject keyId of trusted CA certificates via 'dir-cli trustedcert list' output
|
||||
The result will be cached
|
||||
|
||||
:param use_cache: If True, the previous cached result will be used (default: True)
|
||||
:return: list of subject keyIds of trusted CA certificates
|
||||
"""
|
||||
global cache_ca_keyids
|
||||
if use_cache and cache_ca_keyids is not None:
|
||||
return cache_ca_keyids
|
||||
|
||||
env = Environment.get_environment()
|
||||
sso_username = env.get_value('SSO_USERNAME')
|
||||
sso_password = env.get_value('SSO_PASSWORD')
|
||||
args = [DIR_CLI, 'trustedcert', 'list', '--login', sso_username, '--password', sso_password]
|
||||
ret, stdout, _ = CommandRunner(*args).run()
|
||||
cache_ca_keyids = TextFilter(stdout).start_with('CN(id):').cut(':', [1]).remove_white_spaces().get_lines()
|
||||
return cache_ca_keyids
|
||||
|
||||
|
||||
def get_ca_certificate(subject_keyid, use_cache=True):
|
||||
"""
|
||||
Get CA certificate in VMDir via 'dir-cli trustedcert get' command output
|
||||
|
||||
:param subject_keyid: the certificate' subject keyId
|
||||
:param use_cache: if True, the previous cached result will be used instead
|
||||
:return: trusted CA certificate in PEM format
|
||||
"""
|
||||
global cache_ca_certificate_map
|
||||
if not subject_keyid:
|
||||
return None
|
||||
if use_cache:
|
||||
cert_cache = cache_ca_certificate_map.get(subject_keyid)
|
||||
if cert_cache:
|
||||
return cert_cache
|
||||
|
||||
env = Environment.get_environment()
|
||||
sso_username = env.get_value('SSO_USERNAME')
|
||||
sso_password = env.get_value('SSO_PASSWORD')
|
||||
args = [DIR_CLI, 'trustedcert', 'get', '--login', sso_username, '--password', sso_password,
|
||||
'--id', subject_keyid, '--outcert', '/dev/stdout']
|
||||
ret, stdout, _ = CommandRunner(*args).run()
|
||||
lines = TextFilter(stdout).match_block('-----BEGIN CERTIFICATE-----',
|
||||
'-----END CERTIFICATE-----').get_lines()
|
||||
pem_cert = '\n'.join(lines)
|
||||
cache_ca_certificate_map[subject_keyid] = pem_cert
|
||||
return pem_cert
|
||||
|
||||
|
||||
def get_all_ca_certificates():
|
||||
"""
|
||||
Get all trusted CA certificates in VMDir via dir-cli command)
|
||||
|
||||
:return: list of CA certificates in PEM format
|
||||
"""
|
||||
subject_keyids = get_all_ca_subject_keyids(False)
|
||||
certs = []
|
||||
for subject_keyid in subject_keyids:
|
||||
pem_cert = get_ca_certificate(subject_keyid)
|
||||
certs.append(pem_cert)
|
||||
return certs, subject_keyids
|
||||
|
||||
|
||||
def get_service_principals():
|
||||
"""
|
||||
Get service principal list from VMDir via dir-cli
|
||||
|
||||
:return: list of service principals
|
||||
"""
|
||||
env = Environment.get_environment()
|
||||
sso_username = env.get_value('SSO_USERNAME')
|
||||
sso_password = env.get_value('SSO_PASSWORD')
|
||||
args = [DIR_CLI, 'service', 'list', '--login', sso_username, '--password', sso_password]
|
||||
ret, stdout, _ = CommandRunner(*args).run()
|
||||
return TextFilter(stdout).cut(fields=[1]).get_lines()
|
||||
|
||||
|
||||
def init_env_identity_source():
|
||||
env = Environment.get_environment()
|
||||
if env.get_map().get('SSO_USERNAME') is None or \
|
||||
env.get_value('EXTERNAL_IDENTITY_SOURCE_CONFIGURED') is not None:
|
||||
return
|
||||
|
||||
logger.info('Checking identity source settings')
|
||||
identity_sources = get_identity_sources()
|
||||
source_types = [item['type'] for item in identity_sources]
|
||||
logger.info("Identity sources: {}".format(source_types))
|
||||
|
||||
env.set_value('EXTERNAL_IDENTITY_SOURCE_CONFIGURED', len(source_types) > 0)
|
||||
|
||||
|
||||
def get_identity_sources(use_machine_account=False):
|
||||
"""
|
||||
Get the identity sources settings
|
||||
|
||||
return: list of configured identity source represented in the following dict object:
|
||||
{
|
||||
"type": one of ('AD over LDAP', 'ADFS', 'OpenLDAP')
|
||||
"domain_name": domain name
|
||||
"certificates": CA certificate for this identity source
|
||||
}
|
||||
"""
|
||||
logger.info('Obtaining identity source settings')
|
||||
env = Environment.get_environment()
|
||||
sso_domain = env.get_value('SSO_DOMAIN')
|
||||
domain_dn = env.get_value('SSO_DOMAIN_DN')
|
||||
search_list = [
|
||||
('AD over LDAP', 'IdentityProviders', 'IDENTITY_STORE_TYPE_LDAP_WITH_AD_MAPPING'),
|
||||
('ADFS', 'VCIdentityProviders', 'IDENTITY_STORE_TYPE_LDAP_WITH_AD_MAPPING'),
|
||||
('OpenLDAP', 'IdentityProviders', 'IDENTITY_STORE_TYPE_LDAP')
|
||||
]
|
||||
|
||||
identity_sources = []
|
||||
connection = None
|
||||
try:
|
||||
connection = get_ldap_connection(use_machine_account=use_machine_account)
|
||||
ldap_attributes = ['vmwSTSDomainName', 'userCertificate']
|
||||
for type_name, provider_cn, provider_type in search_list:
|
||||
base_dn = "cn={},cn={},cn=Tenants,cn=IdentityManager,cn=Services,{}"\
|
||||
.format(provider_cn, sso_domain, domain_dn)
|
||||
ldap_filter = "(vmwSTSProviderType={})".format(provider_type)
|
||||
if not Ldap.ldap_search(connection, base_dn, ldap_filter, ldap.SUBTREE, ldap_attributes):
|
||||
# this search may return noSuchObject due to an invalid base_dn
|
||||
if connection.result['result'] == 32:
|
||||
continue
|
||||
logger.error('Unable to perform LDAP search for the identity source setting')
|
||||
raise LdapException(connection.result['result'], connection.result['description'])
|
||||
if not connection.result:
|
||||
continue
|
||||
for entry in connection.response:
|
||||
attributes = entry['attributes']
|
||||
result = dict()
|
||||
result['type'] = type_name
|
||||
result['domain_name'] = attributes['vmwSTSDomainName']
|
||||
certs = []
|
||||
for cert in attributes['userCertificate']:
|
||||
# only expect single certificate
|
||||
certs.append(build_pem_certificate(cert))
|
||||
result['certificates'] = certs
|
||||
identity_sources.append(result)
|
||||
logger.info("Identity source: type={}, domain={}".format(type_name, result['domain_name']))
|
||||
finally:
|
||||
if connection:
|
||||
close_ldap_connection(connection)
|
||||
|
||||
return identity_sources
|
||||
|
||||
|
||||
def get_sso_domain_nodes():
|
||||
logger.info('Obtaining SSO domain nodes')
|
||||
domain_dn = Environment.get_environment().get_value('SSO_DOMAIN_DN')
|
||||
base_dn_list = ["ou=Domain Controllers,{}".format(domain_dn), "ou=Computers,{}".format(domain_dn)]
|
||||
ldap_filter = '(objectClass=computer)'
|
||||
ldap_attributes = ['cn']
|
||||
nodes = []
|
||||
for base_dn in base_dn_list:
|
||||
results = perform_ldap_search(base_dn, ldap_filter, ldap_attributes)
|
||||
for entry in results:
|
||||
node = entry['cn']
|
||||
if node not in nodes:
|
||||
nodes.append(node)
|
||||
logger.info("Found node: {}".format(node))
|
||||
|
||||
return nodes
|
||||
|
||||
|
||||
def get_all_lookup_service_endpoints(search_base=None):
|
||||
"""
|
||||
Get all endpoint entries
|
||||
:return:
|
||||
"""
|
||||
logger.info('Obtaining all endpoints')
|
||||
domain_dn = Environment.get_environment().get_value('SSO_DOMAIN_DN')
|
||||
if search_base is None:
|
||||
search_base = "cn=Sites,cn=Configuration,{}".format(domain_dn)
|
||||
search_filter = '(|(objectclass=vmwLKUPServiceEndpoint)(objectClass=vmwLKUPEndpointRegistration))'
|
||||
search_attributes = ['dn', 'objectClass', 'vmwLKUPURI', 'vmwLKUPEndpointSslTrust', 'vmwLKUPSslTrustAnchor']
|
||||
return perform_ldap_search(search_base, search_filter, search_attributes)
|
||||
|
||||
|
||||
def get_node_trust_anchors(fqdn_or_ip):
|
||||
"""
|
||||
Get SSL trust anchors by filtering the endpoint URI using {fqdn_or_ip}
|
||||
:param fqdn_or_ip:
|
||||
:return:
|
||||
"""
|
||||
logger.info("Obtaining node trust anchors: fqdn_or_ip: {}".format(fqdn_or_ip))
|
||||
trust_anchors = []
|
||||
pattern = "^https://{0}:.*|^https://{0}/.*".format(fqdn_or_ip)
|
||||
endpoints = get_all_lookup_service_endpoints()
|
||||
for endpoint in endpoints:
|
||||
if not re.match(pattern, endpoint['vmwLKUPURI']):
|
||||
continue
|
||||
for cert in sum([endpoint['vmwLKUPEndpointSslTrust'], endpoint['vmwLKUPSslTrustAnchor']], []):
|
||||
pem_cert = certutil.build_pem_certificate(cert)
|
||||
if pem_cert and pem_cert not in trust_anchors:
|
||||
trust_anchors.append(pem_cert)
|
||||
logger.info('Trust anchors found for {}: {}'.format(fqdn_or_ip, trust_anchors))
|
||||
return trust_anchors
|
||||
|
||||
|
||||
def get_endpoint_service_type(service_id):
|
||||
domain_dn = Environment.get_environment().get_value('SSO_DOMAIN_DN')
|
||||
search_base = "cn=Sites,cn=Configuration,{}".format(domain_dn)
|
||||
search_filter = "(cn={})".format(service_id)
|
||||
search_attributes = ['vmwLKUPType']
|
||||
result = perform_ldap_search(search_base, search_filter, search_attributes)
|
||||
if result:
|
||||
return result[0]['vmwLKUPType']
|
||||
|
||||
search_filter = '(objectClass=vmwLKUPService)'
|
||||
search_attributes = ['dn', 'vmwLKUPServiceType']
|
||||
result = perform_ldap_search(search_base, search_filter, search_attributes)
|
||||
for entry in result:
|
||||
if service_id in entry['dn']:
|
||||
# remove prefix 'urn:'
|
||||
return entry['vmwLKUPServiceType'][4:]
|
||||
return ''
|
||||
|
||||
|
||||
def get_registered_vcenters():
|
||||
"""
|
||||
Get registered VCenters
|
||||
:return: list of tuple (deployment_node_id, node_dn)
|
||||
"""
|
||||
logger.info('Obtaining list of registered vCenters')
|
||||
domain_dn = Environment.get_environment().get_value('SSO_DOMAIN_DN')
|
||||
base_dn = "cn=Sites,cn=Configuration,{}".format(domain_dn)
|
||||
ldap_filter = '(vmwLKUPType=vcenterserver)'
|
||||
ldap_attributes = ['vmwLKUPDeploymentNodeId', 'dn']
|
||||
results = perform_ldap_search(base_dn, ldap_filter, ldap_attributes)
|
||||
return [(entry['vmwLKUPDeploymentNodeId'], entry['dn']) for entry in results]
|
||||
|
||||
|
||||
def get_endpoint_registrations(base_dn):
|
||||
ldap_filter = '(objectClass=vmwLKUPEndpointRegistration)'
|
||||
ldap_attributes = ['vmwLKUPURI']
|
||||
results = perform_ldap_search(base_dn, ldap_filter, ldap_attributes)
|
||||
return [entry['vmwLKUPURI'] for entry in results]
|
||||
|
||||
|
||||
def init_env_cac():
|
||||
env = Environment.get_environment()
|
||||
# if env.get_map().get('SSO_USERNAME') is None or \
|
||||
# env.get_value('CAC_CONFIGURED') is not None:
|
||||
# return
|
||||
if env.get_value('CAC_CONFIGURED') is not None:
|
||||
return
|
||||
|
||||
vc_version = get_vc_version()
|
||||
if vc_version >= VcVersion.V9:
|
||||
logger.info('SmartCards are not supported since version {}'.format(VcVersion.V9.value))
|
||||
env.set_value('CAC_CONFIGURED', False)
|
||||
return
|
||||
|
||||
logger.info('Checking SmartCard Authentication settings')
|
||||
sso_domain = env.get_value('SSO_DOMAIN')
|
||||
domain_dn = env.get_value('SSO_DOMAIN_DN')
|
||||
search_base = "cn={},cn=Tenants,cn=IdentityManager,cn=Services,{}".format(sso_domain, domain_dn)
|
||||
search_filter = '(objectclass=vmwSTSTenant)'
|
||||
search_attributes = ['vmwSTSAuthnTypes']
|
||||
results = perform_ldap_search(search_base, search_filter, search_attributes, use_machine_account=True)
|
||||
is_cac_configured = False
|
||||
logger.info('LDAP search results: {}'.format(results))
|
||||
for entry in results:
|
||||
if entry['vmwSTSAuthnTypes'] == 4 or 4 in entry['vmwSTSAuthnTypes']:
|
||||
is_cac_configured = True
|
||||
env.set_value('CAC_CONFIGURED', is_cac_configured)
|
||||
|
||||
|
||||
def get_smart_card_issuing_ca_certs():
|
||||
logger.info('Obtaining SmartCard issuing CA certificates')
|
||||
env = Environment.get_environment()
|
||||
sso_domain = env.get_value('SSO_DOMAIN')
|
||||
domain_dn = env.get_value('SSO_DOMAIN_DN')
|
||||
search_base = \
|
||||
"cn=DefaultClientCertCAStore,cn=ClientCertAuthnTrustedCAs,cn=Default,cn=ClientCertificatePolicies,"\
|
||||
"cn={},cn=Tenants,cn=IdentityManager,cn=Services,{}".format(sso_domain, domain_dn)
|
||||
search_filter = '(objectClass=vmwSTSTenantTrustedCertificateChain)'
|
||||
search_attributes = ['userCertificate']
|
||||
|
||||
result = perform_ldap_search(search_base, search_filter, search_attributes, use_machine_account=True)
|
||||
certs = []
|
||||
for entry in result:
|
||||
certs.extend(build_pem_certificate(cert) for cert in entry['userCertificate'])
|
||||
|
||||
return certs
|
||||
|
||||
|
||||
def get_all_sso_sites():
|
||||
domain_dn = Environment.get_environment().get_value('SSO_DOMAIN_DN')
|
||||
search_base = "cn=Sites,cn=Configuration,{}".format(domain_dn)
|
||||
search_filter = '(objectClass=*)'
|
||||
search_attributes = ['cn']
|
||||
result = perform_ldap_search(search_base, search_filter, search_attributes, search_scope=ldap.LEVEL)
|
||||
return [entry['cn'] for entry in result]
|
||||
|
||||
|
||||
def unpublish_trusted_certificate(cert_file):
|
||||
"""
|
||||
Unpublish certificate in VMDir
|
||||
:param cert_file: Certificate file to unpublish
|
||||
"""
|
||||
env = Environment.get_environment()
|
||||
sso_username = env.get_value('SSO_USERNAME')
|
||||
sso_password = env.get_value('SSO_PASSWORD')
|
||||
CommandRunner(DIR_CLI, 'trustedcert', 'unpublish', '--login', sso_username, '--password',
|
||||
sso_password, '--cert', cert_file, expected_return_code=0).run()
|
||||
|
||||
|
||||
def publish_trusted_certificate(cert_file, is_chain=False):
|
||||
"""
|
||||
Publish certificate in VMDir
|
||||
:param cert_file: Certificate file to unpublish
|
||||
:param is_chain: Publish all certificate in chain
|
||||
"""
|
||||
env = Environment.get_environment()
|
||||
sso_username = env.get_value('SSO_USERNAME')
|
||||
sso_password = env.get_value('SSO_PASSWORD')
|
||||
args = [DIR_CLI, 'trustedcert', 'publish', '--login', sso_username, '--password', sso_password,
|
||||
'--cert', cert_file]
|
||||
if is_chain:
|
||||
args.append('--chain')
|
||||
CommandRunner(*args, expected_return_code=0).run()
|
||||
|
||||
|
||||
def remove_ca_certificate_from_ldap(subject_keyid):
|
||||
domain_dn = Environment.get_environment().get_value('SSO_DOMAIN_DN')
|
||||
cert_dn = "cn={},cn=Certificate-Authorities,cn=Configuration,{}".format(subject_keyid, domain_dn)
|
||||
perform_ldap_delete(cert_dn)
|
||||
|
||||
|
||||
def get_sddc_manager():
|
||||
# SDDC_MANAGER=$($LDAP_SEARCH -LLL -h $PSC_LOCATION -b
|
||||
# "cn=$SSO_DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$VMDIR_DOMAIN_DN"
|
||||
# -D "$VMDIR_MACHINE_ACCOUNT_DN" -y $STAGE_DIR/.machine-account-password '(objectclass=vmwSTSTenant)'
|
||||
# vmwSTSLogonBanner | tr -d '\n' | awk -F'::' '{print $NF}' | tr -d ' ' | base64 -d 2>/dev/null | grep 'SDDC Manager' | awk -F '[()]' '{print $2}' | grep -v '^$')
|
||||
env = Environment.get_environment()
|
||||
sso_domain = env.get_value('SSO_DOMAIN')
|
||||
domain_dn = env.get_value('SSO_DOMAIN_DN')
|
||||
search_base = "cn={},cn=Tenants,cn=IdentityManager,cn=Services,{}".format(sso_domain, domain_dn)
|
||||
search_filter = '(objectClass=vmwSTSTenant)'
|
||||
search_attributes = ['vmwSTSLogonBanner']
|
||||
result = perform_ldap_search(search_base, search_filter, search_attributes, search_scope=ldap.LEVEL)
|
||||
return [entry['cn'] for entry in result]
|
||||
|
||||
|
||||
def update_solution_user_certificate_in_vmdir(soluser, cert_file):
|
||||
env = Environment.get_environment()
|
||||
sso_username = env.get_value('SSO_USERNAME')
|
||||
sso_password = env.get_value('SSO_PASSWORD')
|
||||
machine_id = env.get_value('MACHINE_ID')
|
||||
args = [DIR_CLI, 'service', 'update', '--name', f"{soluser}-{machine_id}", '--cert',
|
||||
cert_file, '--login', sso_username, '--password', sso_password]
|
||||
try:
|
||||
CommandRunner(*args, expected_return_code=0).run_and_get_output()
|
||||
except CommandExecutionError:
|
||||
error_message = f"Unable to update {soluser}-{machine_id} solution user certificate in VMDir"
|
||||
logger.error(error_message)
|
||||
raise OperationFailed(error_message)
|
||||
|
||||
|
||||
# ------------------------------
|
||||
# Replace a Solution User certificate in VMDir
|
||||
# ------------------------------
|
||||
def replace_service_principal_certificates(soluser, cert_file):
|
||||
print_task(f" {soluser}")
|
||||
update_solution_user_certificate_in_vmdir(soluser, cert_file)
|
||||
print_task_status("OK")
|
||||
|
||||
|
||||
def verify_service_principals():
|
||||
print_task('Verifying Service Principal entries exist')
|
||||
service_principals = get_service_principals()
|
||||
if service_principals:
|
||||
env = Environment.get_environment()
|
||||
machine_id = env.get_value('MACHINE_ID')
|
||||
solution_users = env.get_value('SOLUTION_USERS')
|
||||
missing_service_principals = []
|
||||
for solution_user in solution_users:
|
||||
service_principal = "{}-{}".format(solution_user, machine_id)
|
||||
if service_principal not in service_principals:
|
||||
missing_service_principals.append(service_principal)
|
||||
|
||||
if missing_service_principals:
|
||||
print_text_error('ERROR')
|
||||
print_text_error("\n------------------------!!! Attention !!!------------------------ ")
|
||||
print_text_error('The following Service Principal entries are missing:')
|
||||
for sp in missing_service_principals:
|
||||
print_text_error(" - {}".format(sp))
|
||||
|
||||
print_text_error('\nPlease refer to the following Knowledge Base article')
|
||||
print_text_error('on using the lsdoctor utility to recreate the missing')
|
||||
print_text_error('Solution User/Service Principal entries:')
|
||||
print_text_error('https://knowledge.broadcom.com/external/article/320837/using-the-lsdoctor-tool.html')
|
||||
else:
|
||||
print_task_status("OK")
|
||||
else:
|
||||
print_text_error('Could not get list of Service Principal entries from VMware Directory')
|
||||
|
||||
|
||||
def get_vmdir_state():
|
||||
state_output = CommandRunner(VDCADMINTOOL, command_input='6', expected_return_code=0).run_and_get_output()
|
||||
logger.info('VMware Directory state: {}'.format(state_output))
|
||||
service_state = TextFilter(state_output).contain('VmDir State').cut('-', [1]).get_text().strip()
|
||||
return service_state
|
||||
Reference in New Issue
Block a user