From 209592e2d67e17dc743dffc3432f46d4b39621b9 Mon Sep 17 00:00:00 2001 From: Alessandro Pilotti Date: Mon, 17 Feb 2014 19:39:13 +0200 Subject: [PATCH] Metadata service refactoring This refeactoring is required in order to support services that provide metadata in a format which differs from the OpenStack one. --- cloudbaseinit/metadata/factory.py | 23 ++-- cloudbaseinit/metadata/services/base.py | 60 ++++------ .../metadata/services/baseopenstackservice.py | 113 ++++++++++++++++++ .../services/configdrive/configdrive.py | 3 +- .../metadata/services/httpservice.py | 36 ++++-- .../openstack/common/notifier/proxy.py | 3 +- .../plugins/windows/networkconfig.py | 7 +- cloudbaseinit/plugins/windows/sethostname.py | 11 +- .../plugins/windows/setuserpassword.py | 54 +++------ .../plugins/windows/sshpublickeys.py | 11 +- cloudbaseinit/plugins/windows/userdata.py | 4 +- cloudbaseinit/plugins/windows/vds.py | 2 +- .../plugins/windows/winrmcertificateauth.py | 70 ++++------- cloudbaseinit/plugins/windows/x509.py | 1 + cloudbaseinit/shell.py | 4 + .../tests/plugins/windows/test_x509.py | 4 +- 16 files changed, 241 insertions(+), 165 deletions(-) create mode 100644 cloudbaseinit/metadata/services/baseopenstackservice.py diff --git a/cloudbaseinit/metadata/factory.py b/cloudbaseinit/metadata/factory.py index 04f5c694..7ead3337 100644 --- a/cloudbaseinit/metadata/factory.py +++ b/cloudbaseinit/metadata/factory.py @@ -20,17 +20,18 @@ from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.utils import classloader opts = [ - cfg.ListOpt('metadata_services', - default=[ - 'cloudbaseinit.metadata.services.httpservice.HttpService', - 'cloudbaseinit.metadata.services.configdrive.configdrive.' - 'ConfigDriveService', - 'cloudbaseinit.metadata.services.ec2service.EC2Service' - ], - help='List of enabled metadata service classes, ' - 'to be tested fro availability in the provided order. ' - 'The first available service will be used to retrieve ' - 'metadata') + cfg.ListOpt( + 'metadata_services', + default=[ + 'cloudbaseinit.metadata.services.httpservice.HttpService', + 'cloudbaseinit.metadata.services.configdrive.configdrive.' + 'ConfigDriveService', + 'cloudbaseinit.metadata.services.ec2service.EC2Service' + ], + help='List of enabled metadata service classes, ' + 'to be tested fro availability in the provided order. ' + 'The first available service will be used to retrieve ' + 'metadata') ] CONF = cfg.CONF diff --git a/cloudbaseinit/metadata/services/base.py b/cloudbaseinit/metadata/services/base.py index 5c4385a0..0c0ffa88 100644 --- a/cloudbaseinit/metadata/services/base.py +++ b/cloudbaseinit/metadata/services/base.py @@ -15,8 +15,6 @@ # under the License. import abc -import json -import posixpath import time from oslo.config import cfg @@ -53,10 +51,6 @@ class BaseMetadataService(object): def load(self): self._cache = {} - @property - def can_post_password(self): - return False - @abc.abstractmethod def _get_data(self, path): pass @@ -84,41 +78,37 @@ class BaseMetadataService(object): self._cache[path] = data return data - def get_content(self, data_type, name): - path = posixpath.normpath( - posixpath.join(data_type, 'content', name)) - return self._get_cache_data(path) + def get_content(self, name): + pass - def get_user_data(self, data_type, version='latest'): - path = posixpath.normpath( - posixpath.join(data_type, version, 'user_data')) - return self._get_cache_data(path) + def get_user_data(self): + pass - def get_meta_data(self, data_type, version='latest'): - path = posixpath.normpath( - posixpath.join(data_type, version, 'meta_data.json')) - data = self._get_cache_data(path) - if type(data) is str: - return json.loads(self._get_cache_data(path)) - else: - return data + def get_host_name(self): + pass - def _post_data(self, path, data): - raise NotExistingMetadataException() + def get_public_keys(self): + pass - def _get_password_path(self, version='latest'): - return posixpath.normpath(posixpath.join('openstack', - version, - 'password')) + def get_network_config(self): + pass - def is_password_set(self, version='latest'): - path = self._get_password_path(version) - return len(self._get_data(path)) > 0 + def get_admin_password(self): + pass - def post_password(self, enc_password_b64, version='latest'): - path = self._get_password_path(version) - action = lambda: self._post_data(path, enc_password_b64) - return self._exec_with_retry(action) + @property + def can_post_password(self): + return False + + @property + def is_password_set(self): + return False + + def post_password(self, enc_password_b64): + pass + + def get_client_auth_certs(self): + pass def cleanup(self): pass diff --git a/cloudbaseinit/metadata/services/baseopenstackservice.py b/cloudbaseinit/metadata/services/baseopenstackservice.py new file mode 100644 index 00000000..934d0ecc --- /dev/null +++ b/cloudbaseinit/metadata/services/baseopenstackservice.py @@ -0,0 +1,113 @@ +# Copyright 2014 Cloudbase Solutions Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import json +import posixpath +import urllib2 +import urlparse + +from oslo.config import cfg + +from cloudbaseinit.metadata.services import base +from cloudbaseinit.openstack.common import log as logging +from cloudbaseinit.osutils import factory as osutils_factory +from cloudbaseinit.plugins.windows import x509 + +opts = [ + cfg.StrOpt('metadata_base_url', default='http://169.254.169.254/', + help='The base URL where the service looks for metadata'), +] + +CONF = cfg.CONF +CONF.register_opts(opts) + +LOG = logging.getLogger(__name__) + + +class BaseOpenStackService(base.BaseMetadataService): + + def get_content(self, name): + path = posixpath.normpath( + posixpath.join('openstack', 'content', name)) + return self._get_cache_data(path) + + def get_user_data(self): + path = posixpath.normpath( + posixpath.join('openstack', 'latest', 'user_data')) + return self._get_cache_data(path) + + def _get_meta_data(self, version='latest'): + path = posixpath.normpath( + posixpath.join('openstack', version, 'meta_data.json')) + data = self._get_cache_data(path) + if type(data) is str: + return json.loads(self._get_cache_data(path)) + else: + return data + + def get_host_name(self): + return self._get_meta_data().get('hostname') + + def get_public_keys(self): + public_keys = self._get_meta_data().get('public_keys') + if public_keys: + return public_keys.values() + + def get_network_config(self): + return self._get_meta_data().get('network_config') + + def get_admin_password(self): + meta_data = self._get_meta_data() + meta = meta_data.get('meta') + + if meta and 'admin_pass' in meta: + password = meta['admin_pass'] + elif 'admin_pass' in meta_data: + password = meta_data['admin_pass'] + else: + password = None + + return password + + def get_client_auth_certs(self): + cert_data = None + + meta_data = self._get_meta_data() + meta = meta_data.get('meta') + + if meta: + i = 0 + while True: + # Chunking is necessary as metadata items can be + # max. 255 chars long + cert_chunk = meta.get('admin_cert%d' % i) + if not cert_chunk: + break + if not cert_data: + cert_data = cert_chunk + else: + cert_data += cert_chunk + i += 1 + + if not cert_data: + # Look if the user_data contains a PEM certificate + try: + user_data = self.get_user_data() + if user_data.startswith(x509.PEM_HEADER): + cert_data = user_data + except base.NotExistingMetadataException: + LOG.debug("user_data metadata not present") + + if cert_data: + return [cert_data] diff --git a/cloudbaseinit/metadata/services/configdrive/configdrive.py b/cloudbaseinit/metadata/services/configdrive/configdrive.py index e7d4b68b..61be6f67 100644 --- a/cloudbaseinit/metadata/services/configdrive/configdrive.py +++ b/cloudbaseinit/metadata/services/configdrive/configdrive.py @@ -22,6 +22,7 @@ import uuid from oslo.config import cfg from cloudbaseinit.metadata.services import base +from cloudbaseinit.metadata.services import baseopenstackservice from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.metadata.services.configdrive import manager @@ -38,7 +39,7 @@ CONF.register_opts(opts) LOG = logging.getLogger(__name__) -class ConfigDriveService(base.BaseMetadataService): +class ConfigDriveService(baseopenstackservice.BaseOpenStackService): def __init__(self): super(ConfigDriveService, self).__init__() self._metadata_path = None diff --git a/cloudbaseinit/metadata/services/httpservice.py b/cloudbaseinit/metadata/services/httpservice.py index 731a8382..3b20f602 100644 --- a/cloudbaseinit/metadata/services/httpservice.py +++ b/cloudbaseinit/metadata/services/httpservice.py @@ -21,6 +21,7 @@ import urlparse from oslo.config import cfg from cloudbaseinit.metadata.services import base +from cloudbaseinit.metadata.services import baseopenstackservice from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.osutils import factory as osutils_factory @@ -35,7 +36,9 @@ CONF.register_opts(opts) LOG = logging.getLogger(__name__) -class HttpService(base.BaseMetadataService): +class HttpService(baseopenstackservice.BaseOpenStackService): + _POST_PASSWORD_MD_VER = '2013-04-04' + def __init__(self): super(HttpService, self).__init__() self._enable_retry = True @@ -72,17 +75,13 @@ class HttpService(base.BaseMetadataService): self._check_metadata_ip_route() try: - self.get_meta_data('openstack') + self._get_meta_data() return True - except: + except Exception: LOG.debug('Metadata not found at URL \'%s\'' % CONF.metadata_base_url) return False - @property - def can_post_password(self): - return True - def _get_response(self, req): try: return urllib2.urlopen(req) @@ -106,10 +105,27 @@ class HttpService(base.BaseMetadataService): self._get_response(req) return True - def post_password(self, enc_password_b64, version='latest'): + def _get_password_path(self): + return 'openstack/%s/password' % self._POST_PASSWORD_MD_VER + + @property + def can_post_password(self): try: - return super(HttpService, self).post_password(enc_password_b64, - version) + self._get_meta_data(self._POST_PASSWORD_MD_VER) + return True + except base.NotExistingMetadataException: + return False + + @property + def is_password_set(self): + path = self._get_password_path() + return len(self._get_data(path)) > 0 + + def post_password(self, enc_password_b64): + try: + path = self._get_password_path() + action = lambda: self._post_data(path, enc_password_b64) + return self._exec_with_retry(action) except urllib2.HTTPError as ex: if ex.code == 409: # Password already set diff --git a/cloudbaseinit/openstack/common/notifier/proxy.py b/cloudbaseinit/openstack/common/notifier/proxy.py index 69f16898..8553aa1c 100644 --- a/cloudbaseinit/openstack/common/notifier/proxy.py +++ b/cloudbaseinit/openstack/common/notifier/proxy.py @@ -16,7 +16,8 @@ A temporary helper which emulates cloudbaseinit.messaging.Notifier. This helper method allows us to do the tedious porting to the new Notifier API -as a standalone commit so that the commit which switches us to cloudbaseinit.messaging +as a standalone commit so that the commit which switches us to +cloudbaseinit.messaging is smaller and easier to review. This file will be removed as part of that commit. """ diff --git a/cloudbaseinit/plugins/windows/networkconfig.py b/cloudbaseinit/plugins/windows/networkconfig.py index cacc1840..c2ec46a3 100644 --- a/cloudbaseinit/plugins/windows/networkconfig.py +++ b/cloudbaseinit/plugins/windows/networkconfig.py @@ -36,17 +36,16 @@ CONF.register_opts(opts) class NetworkConfigPlugin(base.BasePlugin): def execute(self, service, shared_data): - meta_data = service.get_meta_data('openstack') - if 'network_config' not in meta_data: + network_config = service.get_network_config() + if not network_config: return (base.PLUGIN_EXECUTION_DONE, False) - network_config = meta_data['network_config'] if 'content_path' not in network_config: return (base.PLUGIN_EXECUTION_DONE, False) content_path = network_config['content_path'] content_name = content_path.rsplit('/', 1)[-1] - debian_network_conf = service.get_content('openstack', content_name) + debian_network_conf = service.get_content(content_name) LOG.debug('network config content:\n%s' % debian_network_conf) diff --git a/cloudbaseinit/plugins/windows/sethostname.py b/cloudbaseinit/plugins/windows/sethostname.py index 03af02dc..de665b29 100644 --- a/cloudbaseinit/plugins/windows/sethostname.py +++ b/cloudbaseinit/plugins/windows/sethostname.py @@ -36,14 +36,14 @@ NETBIOS_HOST_NAME_MAX_LEN = 15 class SetHostNamePlugin(base.BasePlugin): def execute(self, service, shared_data): - meta_data = service.get_meta_data('openstack') - if 'hostname' not in meta_data: + osutils = osutils_factory.OSUtilsFactory().get_os_utils() + + metadata_host_name = service.get_host_name() + if not metadata_host_name: LOG.debug('Hostname not found in metadata') return (base.PLUGIN_EXECUTION_DONE, False) - osutils = osutils_factory.OSUtilsFactory().get_os_utils() - - metadata_host_name = meta_data['hostname'].split('.', 1)[0] + metadata_host_name = metadata_host_name.split('.', 1)[0] if (len(metadata_host_name) > NETBIOS_HOST_NAME_MAX_LEN and CONF.netbios_host_name_compatibility): @@ -56,6 +56,7 @@ class SetHostNamePlugin(base.BasePlugin): else: new_host_name = metadata_host_name + LOG.info("Setting hostname: %s" % new_host_name) reboot_required = osutils.set_host_name(new_host_name) return (base.PLUGIN_EXECUTION_DONE, reboot_required) diff --git a/cloudbaseinit/plugins/windows/setuserpassword.py b/cloudbaseinit/plugins/windows/setuserpassword.py index c3a05ee9..3a85db25 100644 --- a/cloudbaseinit/plugins/windows/setuserpassword.py +++ b/cloudbaseinit/plugins/windows/setuserpassword.py @@ -18,7 +18,6 @@ import base64 from oslo.config import cfg -from cloudbaseinit.metadata.services import base as services_base from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.osutils import factory as osutils_factory from cloudbaseinit.plugins import base @@ -38,8 +37,6 @@ LOG = logging.getLogger(__name__) class SetUserPasswordPlugin(base.BasePlugin): - _post_password_md_ver = '2013-04-04' - def _encrypt_password(self, ssh_pub_key, password): cm = crypt.CryptManager() with cm.load_ssh_rsa_public_key(ssh_pub_key) as rsa: @@ -47,29 +44,15 @@ class SetUserPasswordPlugin(base.BasePlugin): return base64.b64encode(enc_password) def _get_ssh_public_key(self, service): - meta_data = service.get_meta_data('openstack', - self._post_password_md_ver) - if not 'public_keys' in meta_data: - return False - - public_keys = meta_data['public_keys'] - ssh_pub_key = None - for k in public_keys: - # Get the first key - ssh_pub_key = public_keys[k] - break - return ssh_pub_key + public_keys = service.get_public_keys() + if public_keys: + return public_keys[0] def _get_password(self, service, osutils): - meta_data = service.get_meta_data('openstack') - meta = meta_data.get('meta') - password = None - if CONF.inject_user_password: - if meta and 'admin_pass' in meta: - password = meta['admin_pass'] - elif 'admin_pass' in meta_data: - password = meta_data['admin_pass'] + password = service.get_admin_password() + else: + password = None if password: LOG.warn('Using admin_pass metadata user password. Consider ' @@ -86,21 +69,13 @@ class SetUserPasswordPlugin(base.BasePlugin): return password def _set_metadata_password(self, password, service): - try: - ssh_pub_key = self._get_ssh_public_key(service) - if ssh_pub_key: - enc_password_b64 = self._encrypt_password(ssh_pub_key, - password) - return service.post_password(enc_password_b64, - self._post_password_md_ver) - else: - LOG.info('No SSH public key available for password encryption') - return True - except services_base.NotExistingMetadataException: - # Requested version not available or password feature - # not implemented - LOG.info('Cannot set the password in the metadata as it is not ' - 'supported by this metadata version') + ssh_pub_key = self._get_ssh_public_key(service) + if ssh_pub_key: + enc_password_b64 = self._encrypt_password(ssh_pub_key, + password) + return service.post_password(enc_password_b64) + else: + LOG.info('No SSH public key available for password encryption') return True def _set_password(self, service, osutils, user_name): @@ -115,8 +90,7 @@ class SetUserPasswordPlugin(base.BasePlugin): user_name = shared_data.get(constants.SHARED_DATA_USERNAME, CONF.username) - if (service.can_post_password and - service.is_password_set(self._post_password_md_ver)): + if service.can_post_password and service.is_password_set: LOG.debug('User\'s password already set in the instance metadata') else: osutils = osutils_factory.OSUtilsFactory().get_os_utils() diff --git a/cloudbaseinit/plugins/windows/sshpublickeys.py b/cloudbaseinit/plugins/windows/sshpublickeys.py index e34be2a6..e75b6479 100644 --- a/cloudbaseinit/plugins/windows/sshpublickeys.py +++ b/cloudbaseinit/plugins/windows/sshpublickeys.py @@ -28,8 +28,9 @@ LOG = logging.getLogger(__name__) class SetUserSSHPublicKeysPlugin(base.BasePlugin): def execute(self, service, shared_data): - meta_data = service.get_meta_data('openstack') - if not 'public_keys' in meta_data: + public_keys = service.get_public_keys() + if not public_keys: + LOG.debug('Public keys not found in metadata') return (base.PLUGIN_EXECUTION_DONE, False) username = CONF.username @@ -47,9 +48,9 @@ class SetUserSSHPublicKeysPlugin(base.BasePlugin): os.makedirs(user_ssh_dir) authorized_keys_path = os.path.join(user_ssh_dir, "authorized_keys") + LOG.info("Writing SSH public keys in: %s" % authorized_keys_path) with open(authorized_keys_path, 'w') as f: - public_keys = meta_data['public_keys'] - for k in public_keys: - f.write(public_keys[k]) + for public_key in public_keys: + f.write(public_key) return (base.PLUGIN_EXECUTION_DONE, False) diff --git a/cloudbaseinit/plugins/windows/userdata.py b/cloudbaseinit/plugins/windows/userdata.py index 3a60a09b..b11f5388 100644 --- a/cloudbaseinit/plugins/windows/userdata.py +++ b/cloudbaseinit/plugins/windows/userdata.py @@ -30,7 +30,7 @@ class UserDataPlugin(base.BasePlugin): def execute(self, service, shared_data): try: - user_data = service.get_user_data('openstack') + user_data = service.get_user_data() except metadata_services_base.NotExistingMetadataException: return (base.PLUGIN_EXECUTION_DONE, False) @@ -127,7 +127,7 @@ class UserDataPlugin(base.BasePlugin): def _end_part_process_event(self, handler_func): LOG.debug("Calling part handler \"__end__\" event") - handler_func(None, "__end__", None, None) + handler_func(None, "__end__", None, None) def _get_plugin_return_value(self, ret_val): plugin_status = base.PLUGIN_EXECUTION_DONE diff --git a/cloudbaseinit/plugins/windows/vds.py b/cloudbaseinit/plugins/windows/vds.py index 4c4355f2..dd804ce9 100644 --- a/cloudbaseinit/plugins/windows/vds.py +++ b/cloudbaseinit/plugins/windows/vds.py @@ -265,7 +265,7 @@ class IVdsDisk(comtypes.IUnknown): comtypes.COMMETHOD([], comtypes.HRESULT, 'QueryExtents', (['out'], ctypes.POINTER(ctypes.POINTER( VDS_DISK_EXTENT)), - 'ppExtentArray'), + 'ppExtentArray'), (['out'], ctypes.POINTER(wintypes.LONG), 'plNumberOfExtents')), ] diff --git a/cloudbaseinit/plugins/windows/winrmcertificateauth.py b/cloudbaseinit/plugins/windows/winrmcertificateauth.py index edf200cb..0d769636 100644 --- a/cloudbaseinit/plugins/windows/winrmcertificateauth.py +++ b/cloudbaseinit/plugins/windows/winrmcertificateauth.py @@ -14,7 +14,6 @@ # License for the specific language governing permissions and limitations # under the License. -from cloudbaseinit.metadata.services import base as metadata_services_base from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.plugins import base from cloudbaseinit.plugins import constants @@ -25,37 +24,6 @@ LOG = logging.getLogger(__name__) class ConfigWinRMCertificateAuthPlugin(base.BasePlugin): - def _get_client_auth_cert(self, service): - cert_data = None - - meta_data = service.get_meta_data('openstack') - meta = meta_data.get('meta') - - if meta: - i = 0 - while True: - # Chunking is necessary as metadata items can be - # max. 255 chars long - cert_chunk = meta.get('admin_cert%d' % i) - if not cert_chunk: - break - if not cert_data: - cert_data = cert_chunk - else: - cert_data += cert_chunk - i += 1 - - if not cert_data: - # Look if the user_data contains a PEM certificate - try: - user_data = service.get_user_data('openstack') - if user_data.startswith(x509.PEM_HEADER): - cert_data = user_data - except metadata_services_base.NotExistingMetadataException: - LOG.debug("user_data metadata not present") - - return cert_data - def _get_credentials(self, shared_data): user_name = shared_data.get(constants.SHARED_DATA_USERNAME) if not user_name: @@ -76,28 +44,34 @@ class ConfigWinRMCertificateAuthPlugin(base.BasePlugin): def execute(self, service, shared_data): user_name, password = self._get_credentials(shared_data) - cert_data = self._get_client_auth_cert(service) - if not cert_data: + certs_data = service.get_client_auth_certs() + if not certs_data: LOG.info("WinRM certificate authentication cannot be configured " "as a certificate has not been provided in the metadata") return (base.PLUGIN_EXECUTION_DONE, False) - cert_manager = x509.CryptoAPICertManager() - cert_thumprint, cert_upn = cert_manager.import_cert( - cert_data, store_name=x509.STORE_NAME_ROOT) - - if not cert_upn: - LOG.error("WinRM certificate authentication cannot be configured " - "as the provided certificate lacks a subject alt name " - "containing an UPN (OID 1.3.6.1.4.1.311.20.2.3)") - return (base.PLUGIN_EXECUTION_DONE, False) - winrm_config = winrmconfig.WinRMConfig() winrm_config.set_auth_config(certificate=True) - if winrm_config.get_cert_mapping(cert_thumprint, cert_upn): - winrm_config.delete_cert_mapping(cert_thumprint, cert_upn) - winrm_config.create_cert_mapping(cert_thumprint, cert_upn, - user_name, password) + for cert_data in certs_data: + cert_manager = x509.CryptoAPICertManager() + cert_thumprint, cert_upn = cert_manager.import_cert( + cert_data, store_name=x509.STORE_NAME_ROOT) + + if not cert_upn: + LOG.error("WinRM certificate authentication cannot be " + "configured as the provided certificate lacks a " + "subject alt name containing an UPN (OID " + "1.3.6.1.4.1.311.20.2.3)") + continue + + if winrm_config.get_cert_mapping(cert_thumprint, cert_upn): + winrm_config.delete_cert_mapping(cert_thumprint, cert_upn) + + LOG.info("Creating WinRM certificate mapping for user " + "%(user_name)s with UPN %(cert_upn)s", + {'user_name': user_name, 'cert_upn': cert_upn}) + winrm_config.create_cert_mapping(cert_thumprint, cert_upn, + user_name, password) return (base.PLUGIN_EXECUTION_DONE, False) diff --git a/cloudbaseinit/plugins/windows/x509.py b/cloudbaseinit/plugins/windows/x509.py index 067bc20b..d04377de 100644 --- a/cloudbaseinit/plugins/windows/x509.py +++ b/cloudbaseinit/plugins/windows/x509.py @@ -37,6 +37,7 @@ STORE_NAME_TRUSTED_PEOPLE = "TrustedPeople" PEM_HEADER = "-----BEGIN CERTIFICATE-----" PEM_FOOTER = "-----END CERTIFICATE-----" + class CryptoAPICertManager(object): def _get_cert_thumprint(self, cert_context_p): thumbprint = None diff --git a/cloudbaseinit/shell.py b/cloudbaseinit/shell.py index f36c6f9c..3fe03808 100644 --- a/cloudbaseinit/shell.py +++ b/cloudbaseinit/shell.py @@ -29,3 +29,7 @@ def main(): logging.setup('cloudbaseinit') init.InitManager().configure_host() + + +if __name__ == "__main__": + main() diff --git a/cloudbaseinit/tests/plugins/windows/test_x509.py b/cloudbaseinit/tests/plugins/windows/test_x509.py index f296ec95..cc78b8cb 100644 --- a/cloudbaseinit/tests/plugins/windows/test_x509.py +++ b/cloudbaseinit/tests/plugins/windows/test_x509.py @@ -192,7 +192,7 @@ class CryptoAPICertManagerTests(unittest.TestCase): mock_CertOpenStore.return_value = store_handle mock_CertAddCertificateContextToStore.return_value = context_to_store if (certstr is None or certificate is None or enhanced_key is None - or store_handle is None or context_to_store is None): + or store_handle is None or context_to_store is None): self.assertRaises(cryptoapi.CryptoAPIException, self._x509.create_self_signed_cert, 'fake subject', 10, True, x509.STORE_NAME_MY) @@ -333,7 +333,7 @@ class CryptoAPICertManagerTests(unittest.TestCase): 0, None, mock_create_unicode_buffer(), 2)] if (not crypttstr or store_handle is None or add_enc_cert is None or - upn_len != 2): + upn_len != 2): self.assertRaises(cryptoapi.CryptoAPIException, self._x509.import_cert, fake_cert_data, True, x509.STORE_NAME_MY)