# vi: ts=4 expandtab
#
# Cloud-Init Datasource for VMware Guestinfo
#
# Copyright (c) 2018 VMware, Inc. All Rights Reserved.
#
# This product is licensed to you under the Apache 2.0 license (the "License").
# You may not use this product except in compliance with the Apache 2.0 License.
#
# This product may include a number of subcomponents with separate copyright
# notices and license terms. Your use of these subcomponents is subject to the
# terms and conditions of the subcomponent's license, as noted in the LICENSE
# file.
#
# Authors: Anish Swaminathan <anishs@vmware.com>
#          Andrew Kutz <akutz@vmware.com>
#
import os
import base64
import zlib
import json

from cloudinit import log as logging
from cloudinit import sources
from cloudinit import util
from cloudinit import safeyaml

from distutils.spawn import find_executable

LOG = logging.getLogger(__name__)

# from cloud-init >= 20.3 subp is in its own module
try:
    from cloudinit.subp import subp, ProcessExecutionError
except ImportError:
    from cloudinit.util import subp, ProcessExecutionError

# This cloud-init datasource was designed for use with CentOS 7,
# which uses cloud-init 0.7.9. However, this datasource should
# work with any Linux distribution for which cloud-init is
# avaialble.
#
# The documentation for cloud-init 0.7.9's datasource is
# available at http://bit.ly/cloudinit-datasource-0-7-9. The
# current documentation for cloud-init is found at
# https://cloudinit.readthedocs.io/en/latest/.
#
# Setting the hostname:
#     The hostname is set by way of the metadata key "local-hostname".
#
# Setting the instance ID:
#     The instance ID may be set by way of the metadata key "instance-id".
#     However, if this value is absent then then the instance ID is
#     read from the file /sys/class/dmi/id/product_uuid.
#
# Configuring the network:
#     The network is configured by setting the metadata key "network"
#     with a value consistent with Network Config Versions 1 or 2,
#     depending on the Linux distro's version of cloud-init:
#
#         Network Config Version 1 - http://bit.ly/cloudinit-net-conf-v1
#         Network Config Version 2 - http://bit.ly/cloudinit-net-conf-v2
#
#     For example, CentOS 7's official cloud-init package is version
#     0.7.9 and does not support Network Config Version 2. However,
#     this datasource still supports supplying Network Config Version 2
#     data as long as the Linux distro's cloud-init package is new
#     enough to parse the data.
#
#     The metadata key "network.encoding" may be used to indicate the
#     format of the metadata key "network". Valid encodings are base64
#     and gzip+base64.
class DataSourceVMwareGuestInfo(sources.DataSource):
    def __init__(self, sys_cfg, distro, paths, ud_proc=None):
        sources.DataSource.__init__(self, sys_cfg, distro, paths, ud_proc)
        self.vmtoolsd = find_executable("vmtoolsd")
        if not self.vmtoolsd:
            LOG.error("Failed to find vmtoolsd")

    def get_data(self):
        if not self.vmtoolsd:
            LOG.error("vmtoolsd is required to fetch guestinfo value")
            return False

        # Get the JSON metadata. Can be plain-text, base64, or gzip+base64.
        metadata = self._get_encoded_guestinfo_data('metadata')
        if metadata:
            try:
                self.metadata = json.loads(metadata)
            except:
                self.metadata = safeyaml.load(metadata)

        # Get the YAML userdata. Can be plain-text, base64, or gzip+base64.
        self.userdata_raw = self._get_encoded_guestinfo_data('userdata')

        # Get the YAML vendordata. Can be plain-text, base64, or gzip+base64.
        self.vendordata_raw = self._get_encoded_guestinfo_data('vendordata')

        return True

    @property
    def network_config(self):
        # Pull the network configuration out of the metadata.
        if self.metadata and 'network' in self.metadata:
            data = self._get_encoded_metadata('network')
            if data:
                # Load the YAML-formatted network data into an object
                # and return it.
                net_config = safeyaml.load(data)
                LOG.debug("Loaded network config: %s", net_config)
                return net_config
        return None

    def get_instance_id(self):
        # Pull the instance ID out of the metadata if present. Otherwise
        # read the file /sys/class/dmi/id/product_uuid for the instance ID.
        if self.metadata and 'instance-id' in self.metadata:
            return self.metadata['instance-id']
        with open('/sys/class/dmi/id/product_uuid', 'r') as id_file:
            return str(id_file.read()).rstrip()

    def _get_encoded_guestinfo_data(self, key):
        data = self._get_guestinfo_value(key)
        if not data:
            return None
        enc_type = self._get_guestinfo_value(key + '.encoding')
        return self._get_encoded_data('guestinfo.' + key, enc_type, data)

    def _get_encoded_metadata(self, key):
        if not self.metadata or not key in self.metadata:
            return None
        data = self.metadata[key]
        enc_type = self.metadata.get(key + '.encoding')
        return self._get_encoded_data('metadata.' + key, enc_type, data)

    def _get_encoded_data(self, key, enc_type, data):
        '''
        The _get_encoded_data would always return a str
        ----
        In py 2.7:
        json.loads method takes string as input
        zlib.decompress takes and returns a string
        base64.b64decode takes and returns a string
        -----
        In py 3.6 and newer:
        json.loads method takes bytes or string as input
        zlib.decompress takes and returns a bytes
        base64.b64decode takes bytes or string and returns bytes
        -----
        In py > 3, < 3.6:
        json.loads method takes string as input
        zlib.decompress takes and returns a bytes
        base64.b64decode takes bytes or string and returns bytes
        -----
        Given the above conditions the output from zlib.decompress and
        base64.b64decode would be bytes with newer python and str in older
        version. Thus we would covert the output to str before returning
        '''
        rawdata = self._get_encoded_data_raw(key, enc_type, data)
        if type(rawdata) == bytes:
            return rawdata.decode('utf-8')
        return rawdata

    def _get_encoded_data_raw(self, key, enc_type, data):
        LOG.debug("Getting encoded data for key=%s, enc=%s", key, enc_type)
        if enc_type == "gzip+base64" or enc_type == "gz+b64":
            LOG.debug("Decoding %s format %s", enc_type, key)
            return zlib.decompress(base64.b64decode(data), zlib.MAX_WBITS | 16)
        elif enc_type == "base64" or enc_type == "b64":
            LOG.debug("Decoding %s format %s", enc_type, key)
            return base64.b64decode(data)
        else:
            LOG.debug("Plain-text data %s", key)
            return data

    def _get_guestinfo_value(self, key):
        NOVAL = "No value found"
        LOG.debug("Getting guestinfo value for key %s", key)
        try:
            (stdout, stderr) = subp([self.vmtoolsd, "--cmd", "info-get guestinfo." + key])
            if stderr == NOVAL:
                LOG.debug("No value found for key %s", key)
            elif not stdout:
                LOG.error("Failed to get guestinfo value for key %s", key)
            else:
                return stdout.rstrip()
        except ProcessExecutionError as error:
            if error.stderr == NOVAL:
                LOG.debug("No value found for key %s", key)
            else:
                util.logexc(LOG,"Failed to get guestinfo value for key %s: %s", key, error)
        except Exception:
            util.logexc(LOG,"Unexpected error while trying to get guestinfo value for key %s", key)
        return None

def get_datasource_list(depends):
    """
    Return a list of data sources that match this set of dependencies
    """
    return [DataSourceVMwareGuestInfo]
