Skip to content

Commit

Permalink
Add support for environment variable substitution
Browse files Browse the repository at this point in the history
  • Loading branch information
ocelotl committed Dec 16, 2023
1 parent cc396e7 commit d70793a
Show file tree
Hide file tree
Showing 5 changed files with 532 additions and 21 deletions.
6 changes: 4 additions & 2 deletions prototypes/python/src/opentelemetry/configuration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
process_schema,
render_schema,
create_object,
load_configuration
load_configuration,
substitute_environment_variables,
)

__all__ = [
Expand All @@ -33,5 +34,6 @@
"process_schema",
"render_schema",
"create_object",
"load_configuration"
"load_configuration",
"substitute_environment_variables",
]
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from ipdb import set_trace
from os import environ
from yaml import safe_load
from re import compile as re_compile
from jsonref import JsonRef
from os.path import exists
from pathlib import Path
Expand All @@ -25,6 +28,18 @@
from opentelemetry.configuration._internal.path_function import path_function
from jinja2 import Environment, FileSystemLoader

set_trace

_environment_variable_regex = re_compile(r"\$\{([a-zA-Z]\w*)\}")
_type_type = {
"integer": int,
"boolean": bool,
"string": str,
"array": list,
"object": object,
"number": float
}


def resolve_schema(json_file_path) -> dict:

Expand Down Expand Up @@ -69,15 +84,6 @@ def retrieve_from_path(path: str):

def process_schema(schema: dict) -> dict:

type_type = {
"integer": "int",
"boolean": "bool",
"string": "str",
"array": "list",
"object": "object",
"number": "float"
}

def traverse(
schema: dict,
schema_value_id_stack: list,
Expand Down Expand Up @@ -117,21 +123,28 @@ def traverse(
for positional_attribute in positional_attributes:

result_positional_attributes[positional_attribute] = (
type_type[
schema_properties[positional_attribute]["type"]
]
str(
_type_type[
schema_properties[positional_attribute]["type"]
].__name__
)
)

for optional_attribute in optional_attributes:

result_optional_attributes[optional_attribute] = (
type_type[
schema_properties[optional_attribute]["type"]
]
str(
_type_type[
schema_properties[optional_attribute]["type"]
].__name__
)
)

children = {}

children.update(result_positional_attributes)
children.update(result_optional_attributes)

processed_schema[schema_key_stack[-1]] = {
"function_name": "_".join(schema_key_stack[1:]),
"positional_attributes": result_positional_attributes,
Expand Down Expand Up @@ -213,7 +226,7 @@ def traverse(
return processed_schema[""]["children"]


def render_schema(processed_schema: dict):
def render_schema(processed_schema: dict, path_function_path: Path):

def traverse(
processed_schema: dict,
Expand All @@ -226,6 +239,9 @@ def traverse(
processed_schema_value
) in processed_schema.items():

if not isinstance(processed_schema_value, dict):
continue

function_arguments[processed_schema_value["function_name"]] = {
"optional_attributes": (
processed_schema_value["optional_attributes"]
Expand Down Expand Up @@ -262,7 +278,7 @@ def traverse(
loader=FileSystemLoader(current_path.joinpath("templates"))
)

with open("path_function.py", "w") as result_py_file:
with open(path_function_path, "w") as result_py_file:

result_py_file.write(
"\n".join(
Expand Down Expand Up @@ -370,3 +386,67 @@ def create_object(
processed_schema,
path_function,
)


def substitute_environment_variables(
configuration: dict,
processed_schema: dict
) -> dict:

def traverse(
configuration: dict,
processed_schema: dict,
original_processed_schema: dict
):

for configuration_key, configuration_value in configuration.items():

if configuration_key not in processed_schema.keys():
continue

if isinstance(configuration_value, dict):

recursive_paths = (
processed_schema[configuration_key]["recursive_path"]
)

if recursive_paths:

children = original_processed_schema

for recursive_path in recursive_paths:
children = children[recursive_path]["children"]

else:
children = processed_schema[configuration_key]["children"]

traverse(
configuration_value,
children,
original_processed_schema
)

elif isinstance(configuration_value, list):

for element in configuration_value:
if isinstance(element, dict):
traverse(
element,
processed_schema[configuration_key]["children"],
original_processed_schema
)

elif isinstance(configuration_value, str):

match = _environment_variable_regex.match(configuration_value)

if match is not None:

configuration[configuration_key] = (
__builtins__[processed_schema[configuration_key]]
(environ.get(match.group(1)))
)

traverse(configuration, processed_schema, processed_schema)

return configuration
Loading

0 comments on commit d70793a

Please sign in to comment.