Skip to content

Commit

Permalink
Added env variable support for himl
Browse files Browse the repository at this point in the history
  • Loading branch information
ecojan committed Jul 14, 2021
1 parent fd2078d commit d1262aa
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 1 deletion.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ remote_states:
endpoint: "{{outputs.cluster_composition.output.value.redis_endpoint}}"
```

### Merge with env variables
```yaml
kubeconfig_location: {{env(KUBECONFIG)}}
```


## himl config merger

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
cluster: cluster1
home: {{env(HOME)}}
10 changes: 9 additions & 1 deletion himl/config_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
import yaml
from deepmerge import Merger

from .interpolation import InterpolationResolver, EscapingResolver, InterpolationValidator, SecretResolver, DictIterator, replace_parent_working_directory
from .interpolation import InterpolationResolver, EscapingResolver, InterpolationValidator, SecretResolver, \
DictIterator, replace_parent_working_directory, EnvVarResolver
from .python_compat import iteritems, primitive_types, PY3
from .remote_state import S3TerraformRemoteStateRetriever

Expand Down Expand Up @@ -68,6 +69,9 @@ def process(self, cwd=None, path=None, filters=(), exclude_keys=(), enclosing_ke
# value2: "something-{{value1}} <--- this will be resolved at this step
generator.resolve_interpolations()

generator.resolve_env()
generator.resolve_interpolations()

if len(filters) > 0:
generator.filter_data(filters)

Expand Down Expand Up @@ -279,6 +283,10 @@ def resolve_secrets(self, default_aws_profile):
resolver = SecretResolver()
self.generated_data = resolver.resolve_secrets(self.generated_data, default_aws_profile)

def resolve_env(self):
resolver = EnvVarResolver()
self.generated_data = resolver.resolve_env_vars(self.generated_data)

def validate_interpolations(self):
self.interpolation_validator.check_all_interpolations_resolved(self.generated_data)

Expand Down
50 changes: 50 additions & 0 deletions himl/inject_env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright 2021 Adobe. All rights reserved.
# This file is licensed to you 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 REPRESENTATIONS
# OF ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.

from os import getenv


class EnvVarInjector(object):
"""
Resolve variables in the form:
{{env(HOME)}}
"""

def __init__(self):
return

def is_interpolation(self, value):
return value.startswith('{{') and value.endswith('}}')

def inject_env_var(self, line):
"""
Check if value is an interpolation and try to resolve it.
"""
if not self.is_interpolation(line):
return line

# remove {{ and }}
updated_line = line[2:-2]

# check supported function to ensure the proper format is used
if not self.check_supported_function(updated_line):
return line

# remove env( and ) to extract the env Variable
updated_line = updated_line[4:-1]

# If env variable is missing or not set, the output will be None
return getenv(updated_line)

def check_supported_function(self, value):
return value.startswith('env(') and value.endswith(')')

def split_function_items(self, line):
line.split()
18 changes: 18 additions & 0 deletions himl/interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import re

from .inject_env import EnvVarInjector
from .inject_secrets import SecretInjector
from .python_compat import iteritems, string_types, primitive_types

Expand Down Expand Up @@ -83,6 +84,14 @@ def resolve_secrets(self, data, default_aws_profile):
return data


class EnvVarResolver(object):
def resolve_env_vars(self, data):
injector = EnvVarInjector()
env_resolver = EnvVarInterpolationsResolver(injector)
env_resolver.resolve_interpolations(data)
return data


class DictIterator(object):

def loop_all_items(self, data, process_func):
Expand Down Expand Up @@ -168,6 +177,15 @@ def do_resolve_interpolation(self, line):
return self.secrets_injector.inject_secret(line)


class EnvVarInterpolationsResolver(AbstractInterpolationResolver):
def __init__(self, env_vars_injector):
AbstractInterpolationResolver.__init__(self)
self.env_vars_injector = env_vars_injector

def do_resolve_interpolation(self, line):
return self.env_vars_injector.inject_env_var(line)


class InterpolationValidator(DictIterator):

def check_all_interpolations_resolved(self, data):
Expand Down

0 comments on commit d1262aa

Please sign in to comment.