403Webshell
Server IP : 3.96.16.70  /  Your IP : 216.73.216.15
Web Server : Apache
System : Linux ip-172-31-26-103.ca-central-1.compute.internal 6.1.163-186.299.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Feb 24 16:35:42 UTC 2026 x86_64
User : ec2-user ( 1000)
PHP Version : 8.4.18
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /lib/python3.9/site-packages/cloudinit/config/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /lib/python3.9/site-packages/cloudinit/config/cc_write_metadata.py
# Copyright (C) 2012 Yahoo! Inc.
# Copyright (C) 2014 Amazon.com, Inc. or its affiliates.
#
# Author: Joshua Harlow <harlowja@yahoo-inc.com>
# Author: Iliana Weller <iweller@amazon.com>
#
# This file is part of cloud-init. See LICENSE file for license information.

from textwrap import dedent

from cloudinit.config import cc_write_files
from cloudinit.config.schema import MetaSchema, get_meta_doc
from cloudinit.settings import PER_INSTANCE
from cloudinit import util

frequency = PER_INSTANCE

# list of dictionaries we expose to the user from the cloud.datasource object
EXPOSED_DICTS = ('metadata', 'identity')
# list of optional arguments not supported by write_files
OPTIONAL_ARGUMENTS = ('separator', 'allowempty')


meta: MetaSchema = {
    "id": "cc_write_metadata",
    "name": "Write Metadata",
    "title": "write IMDS data to arbitrary files",
    "frequency": PER_INSTANCE,
    "description": dedent(
    """\
    Example cloud-config that would write the AWS instance ID to
    /root/.instance-id, with a fallback of "unknown":

    write_metadata:
      - path: /root/.instance-id
        data:
          - metadata: instance-id
          - unknown

    Available places to get data from include identity and metadata.
    Data paths can include slashes as delimiters in the dictionary
    structure; a user can provide their own delimiter if needed:

    write_metadata:
      - path: /root/whatever
        data:
          - metadata: public-keys|this/has/slashes|0
            separator: "|"
          - fallback string

    write_metadata will consider an empty string from a data path an
    error, unless you specifically say that's okay with "allowempty":

    write_metadata:
      - path: /root/.could-be-blank
        data:
          - metadata: could-be-blank
            allowempty: true
          - fallback string
    """),
    "distros": ["all"],
    "examples": [
        dedent(
            """\
    write_metadata:
      - path: /root/.instance-id
        data:
          - metadata: instance-id
          - unknown
            """
        ),
        dedent(
            """\
    write_metadata:
        - path: /instance-region
          data:
            - identity: region
            - unknown region
            """
        )
    ]
}

__doc__ = get_meta_doc(meta)


def handle(name, cfg, cloud, log, args):
    """
    Example cloud-config that would write the AWS instance ID to
    /root/.instance-id, with a fallback of "unknown":

    write_metadata:
      - path: /root/.instance-id
        data:
          - metadata: instance-id
          - unknown

    Available places to get data from include identity and metadata.
    Data paths can include slashes as delimiters in the dictionary
    structure; a user can provide their own delimiter if needed:

    write_metadata:
      - path: /root/whatever
        data:
          - metadata: public-keys|this/has/slashes|0
            separator: "|"
          - fallback string

    write_metadata will consider an empty string from a data path an
    error, unless you specifically say that's okay with "allowempty":

    write_metadata:
      - path: /root/.could-be-blank
        data:
          - metadata: could-be-blank
            allowempty: true
          - fallback string
    """
    files = cfg.get('write_metadata')
    if not files:
        log.debug(("Skipping module named %s, no/empty "
                   "'write_metadata' key in configuration"), name)
        return
    write_metadata(name, files, cloud, log)


def write_metadata(name, files, cloud, log):
    if not files:
        return

    new_files = list()

    for i, f_info in enumerate(files):
        path = f_info.get('path')
        if not path:
            log.warn("No path provided to write for entry %s in module %s",
                     i + 1, name)
            continue
        data = f_info.get('data')
        if not data:
            log.warn("No data provided to write for entry %s in module %s",
                     i + 1, name)
            continue

        f_info['content'] = retrieve_metadata(path, data, cloud, log)
        if f_info['content'] is None:
            # if there is no content, don't write anything to the file
            # (this is not the same as empty content)
            continue

        # Use the default permissions, to suppress a warning from write-files
        f_info.setdefault('permissions', cc_write_files.DEFAULT_PERMS)

        # ensure that we don't get unexpected behavior in a future
        # version of the write_files module
        for key in EXPOSED_DICTS + OPTIONAL_ARGUMENTS:
            if key in f_info:
                del f_info[key]

        new_files.append(f_info)

    cc_write_files.write_files(name, files)


def retrieve_metadata(path, data, cloud, log):
    for datum in data:
        if isinstance(datum, str):
            # used for fallback data
            return datum
        elif isinstance(datum, dict):
            kwargs = dict()
            if 'separator' in datum:
                kwargs['separator'] = datum['separator']
            for dataset in EXPOSED_DICTS:
                if dataset in datum:
                    if not hasattr(cloud.datasource, dataset):
                        log.warn('there is no %s dataset', dataset)
                        continue
                    try:
                        obj = getattr(cloud.datasource, dataset)
                        value = util.dictpath(obj, datum[dataset], **kwargs)
                        # if the value is an empty string, and the
                        # configuration hasn't told us that's okay, go
                        # to the next fallback
                        if not value and \
                                util.is_false(datum.get('allowempty', False)):
                            continue
                        return value
                    except Exception as exc:
                        # don't return anything, we proceed to the next datum
                         log.warn('using path %(path)s against %(dataset)s '
                                  'failed: %(exctype)s: %(excmsg)s' %
                                  { 'path' : datum[dataset],
                                    'dataset' : dataset,
                                    'exctype': type(exc).__name__,
                                    'excmsg' : str(exc)
                                   })

    # if we reached this point, all attempts to get the data we want
    # failed, and there wasn't a fallback
    log.warn('all attempts to retrieve metadata for %s failed', path)

# vi: ts=4 expandtab

Youez - 2016 - github.com/yon3zu
LinuXploit