diff --git a/README.md b/README.md index d6c9d92..812cf05 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,10 @@ Idea came from puppet's hiera. ```sh pip install himl +# or, optionally install with all extras dependencies: vault and s3 interpolation support +pip install himl[all] +# or, specify which extras dependencies you need +pip install himl[vault,s3] ``` ### Using `docker` image diff --git a/himl/config_generator.py b/himl/config_generator.py index 67eb950..042ce03 100755 --- a/himl/config_generator.py +++ b/himl/config_generator.py @@ -295,8 +295,9 @@ def exclude_keys(self, keys): logger.info("Excluded key %s not found or already removed", key) def add_dynamic_data(self): - remote_state_retriever = S3TerraformRemoteStateRetriever() if "remote_states" in self.generated_data: + from .remote_state import S3TerraformRemoteStateRetriever + remote_state_retriever = S3TerraformRemoteStateRetriever() state_files = self.generated_data["remote_states"] remote_states = remote_state_retriever.get_dynamic_data(state_files) self.merge_value(self.generated_data, remote_states, self.type_strategies, self.fallback_strategies, diff --git a/himl/remote_state.py b/himl/remote_state.py index 14ea6b5..e1bd5e2 100644 --- a/himl/remote_state.py +++ b/himl/remote_state.py @@ -10,8 +10,10 @@ import json -import boto3 - +try: + import boto3 +except ImportError as e: + raise Exception('Error while trying to read remote state, package "boto3" is required and cannot be imported: %s' % e) class S3TerraformRemoteStateRetriever: @staticmethod diff --git a/himl/secret_resolvers.py b/himl/secret_resolvers.py index 0558c36..fbf8370 100644 --- a/himl/secret_resolvers.py +++ b/himl/secret_resolvers.py @@ -10,9 +10,6 @@ import logging import os -from .simplessm import SimpleSSM -from .simples3 import SimpleS3 -from .simplevault import SimpleVault class SecretResolver: @@ -33,7 +30,7 @@ def __init__(self, default_aws_profile=None): self.default_aws_profile = default_aws_profile def supports(self, secret_type): - return secret_type == "ssm" + return "boto3" in sys.modules && secret_type == "ssm" def resolve(self, secret_type, secret_params): aws_profile = secret_params.get("aws_profile", self.default_aws_profile) @@ -43,6 +40,7 @@ def resolve(self, secret_type, secret_params): path = self.get_param_or_exception("path", secret_params) region_name = secret_params.get("region_name", "us-east-1") + from .simplessm import SimpleSSM ssm = SimpleSSM(aws_profile, region_name) return ssm.get(path) @@ -52,7 +50,7 @@ def __init__(self, default_aws_profile=None): self.default_aws_profile = default_aws_profile def supports(self, secret_type): - return secret_type == "s3" + return "boto3" in sys.modules && secret_type == "s3" def resolve(self, secret_type, secret_params): aws_profile = secret_params.get("aws_profile", self.default_aws_profile) @@ -65,15 +63,17 @@ def resolve(self, secret_type, secret_params): region_name = secret_params.get("region_name", "us-east-1") base64Encode = secret_params.get("base64encode", False) base64Encode = base64Encode == 'true' + from .simples3 import SimpleS3 s3 = SimpleS3(aws_profile, region_name) return s3.get(bucket, path, base64Encode) class VaultSecretResolver(SecretResolver): def supports(self, secret_type): - return secret_type == "vault" + return "hvac" in sys.modules && secret_type == "vault" def resolve(self, secret_type, secret_params): + from .simplevault import SimpleVault vault = SimpleVault # Generate a token for a policy @@ -106,4 +106,4 @@ def resolve(self, secret_type, secret_params): if resolver.supports(secret_type): return resolver.resolve(secret_type, secret_params) - raise Exception("Could not resolve secret type '{}' with params {}".format(secret_type, secret_params)) + raise Exception("Could not resolve secret type '{}' with params {}. Check if you installed the required 3rd party modules.".format(secret_type, secret_params)) diff --git a/setup.py b/setup.py index 072a454..30da1ff 100644 --- a/setup.py +++ b/setup.py @@ -15,10 +15,18 @@ 'backports.functools_lru_cache==1.6.6', 'pathlib2==2.3.7.post1', 'pyyaml==6.0.1', - 'boto3==1.34.6', - 'hvac==1.2.1' ] +_extras_require = { + 's3': [ + 'boto3==1.34.6', + ], + 'vault': [ + 'hvac==1.2.1', + ], +} +_extras_require['all'] = [dep for deps in _extras_require.values() for dep in deps] + setup( name='himl', version="0.15.1", @@ -54,6 +62,7 @@ packages=['himl'], include_package_data=True, install_requires=_install_requires, + extras_require=_extras_require, entry_points={ 'console_scripts': [ 'himl = himl.main:run',