From 40daaa25d61b126c2755e4e0eb80c16f7c8e4440 Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 28 May 2021 15:25:50 +0430 Subject: [PATCH 1/5] Update CloudStack DataServer document --- doc/source/services.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/source/services.rst b/doc/source/services.rst index a38b6438..523d21b2 100644 --- a/doc/source/services.rst +++ b/doc/source/services.rst @@ -265,12 +265,12 @@ Config options for `default` section: .. note:: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html -Apache CloudStack +Apache CloudStack (DataServer) ----------------- -.. class:: cloudbaseinit.metadata.services.cloudstack.CloudStack +.. class:: cloudbaseinit.metadata.services.cloudstack.DataServer -Another web-based service which usually uses "10.1.1.1" or DHCP addresses for +Another web-based service which usually uses "data-server" DNS record or DHCP addresses for retrieving content. If no metadata can be found at the `metadata_base_url`, the service will look for the metadata at the DHCP server URL. @@ -285,7 +285,7 @@ Capabilities: Config options for `cloudstack` section: - * metadata_base_url (string: "http://10.1.1.1/") + * metadata_base_url (string: "http://data-server/") * password_server_port (int: 8080) * add_metadata_private_ip_route (bool: True) * https_allow_insecure (bool: False) From b63d161e8ee0b2831e02a8ac64a8247f64b62b4d Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 28 May 2021 15:26:38 +0430 Subject: [PATCH 2/5] Add CloudStack ConfigDrive document --- doc/source/services.rst | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/doc/source/services.rst b/doc/source/services.rst index 523d21b2..693a5bc1 100644 --- a/doc/source/services.rst +++ b/doc/source/services.rst @@ -302,6 +302,37 @@ Config options for `default` section: and no updating will occur until a new password is available on the server. +.. _configdrive: + +Apache CloudStack (ConfigDrive) +------------------------------- + +.. class:: cloudbaseinit.metadata.services.cloudstack.ConfigDrive + +CloudStack also provides meta-data and user-data with help of CD-ROM without +requiring network access. + +This service is usually faster than the HTTP twin, as there is no timeout +waiting for the network to be up. + +Metadata version used: `latest`. + +Capabilities: + + * instance id + * hostname + * public keys + * admin user password + * user data + +Config options for `cloudstack` section: + + * disk_label (string: "config-2") + +.. note:: By design, this service can update the password anytime, so it will + cause the `setuserpassword` plugin to run at every boot and the password hash + is stored right after retrieval and no updating will occur until a new password + is available on the server. OpenNebula Service ------------------ From e179e59898edf4f2e10b6abbebbf52b397585a42 Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 28 May 2021 18:05:53 +0430 Subject: [PATCH 3/5] Change CloudStack Class name to DataServer --- cloudbaseinit/metadata/services/cloudstack.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cloudbaseinit/metadata/services/cloudstack.py b/cloudbaseinit/metadata/services/cloudstack.py index 7e3a5235..ff9483c2 100644 --- a/cloudbaseinit/metadata/services/cloudstack.py +++ b/cloudbaseinit/metadata/services/cloudstack.py @@ -33,9 +33,9 @@ TIMEOUT = 10 -class CloudStack(base.BaseHTTPMetadataService): +class DataServer(base.BaseHTTPMetadataService): - """Metadata service for Apache CloudStack. + """Metadata service based on DataServer for Apache CloudStack. Apache CloudStack is an open source software designed to deploy and manage large networks of virtual machines, as a highly available, @@ -44,7 +44,7 @@ class CloudStack(base.BaseHTTPMetadataService): """ def __init__(self): - super(CloudStack, self).__init__( + super(DataServer, self).__init__( # Note(alexcoman): The base url used by the current metadata # service will be updated later by the `_test_api` method. base_url=None, @@ -83,7 +83,7 @@ def _test_api(self, metadata_url): def load(self): """Obtain all the required information.""" - super(CloudStack, self).load() + super(DataServer, self).load() if CONF.cloudstack.add_metadata_private_ip_route: network.check_metadata_ip_route(CONF.cloudstack.metadata_base_url) @@ -259,3 +259,8 @@ def can_update_password(self): def is_password_changed(self): """Check if a new password exists in the Password Server.""" return bool(self._get_password()) + + +# For backward compatibiliy, CloudStack Class is an alias to DataServer Class +CloudStack = DataServer + From 53809be82f5b6088369b3c672742bf43a1f418f7 Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 28 May 2021 18:08:02 +0430 Subject: [PATCH 4/5] Add CloudStack ConfigDrive Support --- cloudbaseinit/conf/cloudstack.py | 4 ++ cloudbaseinit/metadata/services/cloudstack.py | 60 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/cloudbaseinit/conf/cloudstack.py b/cloudbaseinit/conf/cloudstack.py index fc20e94f..5052249d 100644 --- a/cloudbaseinit/conf/cloudstack.py +++ b/cloudbaseinit/conf/cloudstack.py @@ -46,6 +46,10 @@ def __init__(self, config): cfg.BoolOpt( "add_metadata_private_ip_route", default=False, help="Add a route for the metadata ip address to the gateway"), + cfg.StrOpt( + "disk_label", default="config-2", + help="Disk label of ConfigDrive" + ) ] def register(self): diff --git a/cloudbaseinit/metadata/services/cloudstack.py b/cloudbaseinit/metadata/services/cloudstack.py index ff9483c2..ef13a3d1 100644 --- a/cloudbaseinit/metadata/services/cloudstack.py +++ b/cloudbaseinit/metadata/services/cloudstack.py @@ -14,6 +14,7 @@ import contextlib import posixpath +import hashlib from oslo_log import log as oslo_logging from six.moves import http_client @@ -21,6 +22,8 @@ from cloudbaseinit import conf as cloudbaseinit_conf from cloudbaseinit.metadata.services import base +from cloudbaseinit.metadata.services import baseconfigdrive +from cloudbaseinit.metadata.services import baseopenstackservice from cloudbaseinit.osutils import factory as osutils_factory from cloudbaseinit.utils import encoding from cloudbaseinit.utils import network @@ -264,3 +267,60 @@ def is_password_changed(self): # For backward compatibiliy, CloudStack Class is an alias to DataServer Class CloudStack = DataServer + +class ConfigDrive(baseconfigdrive.BaseConfigDriveService, + baseopenstackservice.BaseOpenStackService): + + """Metadata service based on ConfigDrive for Apache CloudStack. + + Apache CloudStack is an open source software designed to deploy and + manage large networks of virtual machines, as a highly available, + highly scalable Infrastructure as a Service (IaaS) cloud computing + platform. + """ + + def __init__(self): + super(ConfigDrive, self).__init__( + CONF.cloudstack.disk_label, 'openstack\\latest\\meta_data.json') + + def _preprocess_options(self): + """CloudStack ConfigDrive only supports CD-ROM""" + self._searched_types = set(['iso']) + self._searched_locations = set(['cdrom']) + + def _get_password(self): + """Read password from cloudstack/password/vm_password.txt file if exist + """ + password = None + path = posixpath.normpath( + posixpath.join('cloudstack', 'password', 'vm_password.txt')) + try: + password = self._get_cache_data(path, True) + LOG.info('Password file was found in ConfigDrive') + except base.NotExistingMetadataException: + LOG.info('No password file was found in ConfigDrive') + return password + + def get_admin_password(self): + return self._get_password() + + @property + def can_update_password(self): + """The CloudStack Password Server supports password update.""" + return True + + def is_password_changed(self): + """Check if a new password exists in the ConfigDrive.""" + password = self._get_password() + if password: + osutils = osutils_factory.get_os_utils() + old_password_hash = osutils.get_config_value( + 'PasswordHash', self.get_instance_id()) + new_password_hash = hashlib.sha256( + password.encode('utf-8')).hexdigest() + if old_password_hash != new_password_hash: + LOG.debug('New password is detected') + osutils.set_config_value('PasswordHash', new_password_hash, + self.get_instance_id()) + return True + return False From be973bc7a182f0a52e1b7f6d509a02510c528d4c Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 28 May 2021 18:08:48 +0430 Subject: [PATCH 5/5] Change default CloudStack metadata_base_url --- cloudbaseinit/conf/cloudstack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudbaseinit/conf/cloudstack.py b/cloudbaseinit/conf/cloudstack.py index 5052249d..2c14ba70 100644 --- a/cloudbaseinit/conf/cloudstack.py +++ b/cloudbaseinit/conf/cloudstack.py @@ -27,7 +27,7 @@ def __init__(self, config): super(CloudStackOptions, self).__init__(config, group="cloudstack") self._options = [ cfg.StrOpt( - "metadata_base_url", default="http://10.1.1.1/", + "metadata_base_url", default="http://data-server/", help="The base URL where the service looks for metadata", deprecated_name="cloudstack_metadata_ip", deprecated_group="DEFAULT"),