diff options
author | abikouo <abikouo@redhat.com> | 2024-04-02 18:18:36 +0200 |
---|---|---|
committer | Chris Meyers <chrismeyersfsu@users.noreply.github.com> | 2024-04-16 16:34:38 +0200 |
commit | 199507c6f1f5703a9e08bea7db6fb304dcd9e2b0 (patch) | |
tree | 67be494ff558bde215797b130e0cf197140a032f | |
parent | Update LDAP/SAML config dump command (#15106) (diff) | |
download | awx-199507c6f1f5703a9e08bea7db6fb304dcd9e2b0.tar.xz awx-199507c6f1f5703a9e08bea7db6fb304dcd9e2b0.zip |
Support Google credentials on Terraform credentials type
-rw-r--r-- | awx/main/models/credential/__init__.py | 8 | ||||
-rw-r--r-- | awx/main/models/credential/injectors.py | 7 | ||||
-rw-r--r-- | awx/main/models/inventory.py | 30 | ||||
-rw-r--r-- | awx/main/tests/data/inventory/plugins/terraform/env.json | 2 | ||||
-rw-r--r-- | awx/main/tests/unit/test_tasks.py | 38 |
5 files changed, 81 insertions, 4 deletions
diff --git a/awx/main/models/credential/__init__.py b/awx/main/models/credential/__init__.py index 12b09095c2..894b16ed2c 100644 --- a/awx/main/models/credential/__init__.py +++ b/awx/main/models/credential/__init__.py @@ -1232,6 +1232,14 @@ ManagedCredentialType( 'multiline': True, 'help_text': gettext_noop('Terraform backend config as Hashicorp configuration language.'), }, + { + 'id': 'gce_credentials', + 'label': gettext_noop('Google Cloud Platform account credentials'), + 'type': 'string', + 'secret': True, + 'multiline': True, + 'help_text': gettext_noop('Google Cloud Platform account credentials in JSON format.'), + }, ], 'required': ['configuration'], }, diff --git a/awx/main/models/credential/injectors.py b/awx/main/models/credential/injectors.py index 585bd9597d..29a438f919 100644 --- a/awx/main/models/credential/injectors.py +++ b/awx/main/models/credential/injectors.py @@ -130,3 +130,10 @@ def terraform(cred, env, private_data_dir): os.chmod(path, stat.S_IRUSR | stat.S_IWUSR) f.write(cred.get_input('configuration')) env['TF_BACKEND_CONFIG_FILE'] = to_container_path(path, private_data_dir) + # Handle env variables for GCP account credentials + if 'gce_credentials' in cred.inputs: + handle, path = tempfile.mkstemp(dir=os.path.join(private_data_dir, 'env')) + with os.fdopen(handle, 'w') as f: + os.chmod(path, stat.S_IRUSR | stat.S_IWUSR) + f.write(cred.get_input('gce_credentials')) + env['GOOGLE_BACKEND_CREDENTIALS'] = to_container_path(path, private_data_dir) diff --git a/awx/main/models/inventory.py b/awx/main/models/inventory.py index e4310f08ff..465fdc03b7 100644 --- a/awx/main/models/inventory.py +++ b/awx/main/models/inventory.py @@ -11,6 +11,8 @@ import os.path from urllib.parse import urljoin import yaml +import tempfile +import stat # Django from django.conf import settings @@ -1638,17 +1640,39 @@ class satellite6(PluginFileInjector): class terraform(PluginFileInjector): plugin_name = 'terraform_state' - base_injector = 'managed' namespace = 'cloud' collection = 'terraform' use_fqcn = True def inventory_as_dict(self, inventory_update, private_data_dir): - env = super(terraform, self).get_plugin_env(inventory_update, private_data_dir, None) ret = super().inventory_as_dict(inventory_update, private_data_dir) - ret['backend_config_files'] = env["TF_BACKEND_CONFIG_FILE"] + credential = inventory_update.get_cloud_credential() + config_cred = credential.get_input('configuration') + if config_cred: + handle, path = tempfile.mkstemp(dir=os.path.join(private_data_dir, 'env')) + with os.fdopen(handle, 'w') as f: + os.chmod(path, stat.S_IRUSR | stat.S_IWUSR) + f.write(config_cred) + ret['backend_config_files'] = to_container_path(path, private_data_dir) return ret + def build_plugin_private_data(self, inventory_update, private_data_dir): + credential = inventory_update.get_cloud_credential() + + private_data = {'credentials': {}} + gce_cred = credential.get_input('gce_credentials') + if gce_cred: + private_data['credentials'][credential] = gce_cred + return private_data + + def get_plugin_env(self, inventory_update, private_data_dir, private_data_files): + env = super(terraform, self).get_plugin_env(inventory_update, private_data_dir, private_data_files) + credential = inventory_update.get_cloud_credential() + cred_data = private_data_files['credentials'] + if cred_data[credential]: + env['GOOGLE_BACKEND_CREDENTIALS'] = to_container_path(cred_data[credential], private_data_dir) + return env + class controller(PluginFileInjector): plugin_name = 'tower' # TODO: relying on routing for now, update after EEs pick up revised collection diff --git a/awx/main/tests/data/inventory/plugins/terraform/env.json b/awx/main/tests/data/inventory/plugins/terraform/env.json index c68086c8d7..49e8282433 100644 --- a/awx/main/tests/data/inventory/plugins/terraform/env.json +++ b/awx/main/tests/data/inventory/plugins/terraform/env.json @@ -1,3 +1,3 @@ { - "TF_BACKEND_CONFIG_FILE": "{{ file_reference }}" + "GOOGLE_BACKEND_CREDENTIALS": "{{ file_reference }}" } diff --git a/awx/main/tests/unit/test_tasks.py b/awx/main/tests/unit/test_tasks.py index 703dc72f77..e5b8fbf79e 100644 --- a/awx/main/tests/unit/test_tasks.py +++ b/awx/main/tests/unit/test_tasks.py @@ -1106,6 +1106,44 @@ class TestJobCredentials(TestJobExecution): config = open(local_path, 'r').read() assert config == hcl_config + def test_terraform_gcs_backend_credentials(self, job, private_data_dir, mock_me): + terraform = CredentialType.defaults['terraform']() + hcl_config = ''' + backend "gcs" { + bucket = "gce_storage" + } + ''' + gce_backend_credentials = ''' + { + "type": "service_account", + "project_id": "sample", + "private_key_id": "eeeeeeeeeeeeeeeeeeeeeeeeeee", + "private_key": "-----BEGIN PRIVATE KEY-----\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n-----END PRIVATE KEY-----\n", + "client_email": "sample@sample.iam.gserviceaccount.com", + "client_id": "0123456789", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/cloud-content-robot%40sample.iam.gserviceaccount.com", + } + ''' + credential = Credential(pk=1, credential_type=terraform, inputs={'configuration': hcl_config, 'gce_credentials': gce_backend_credentials}) + credential.inputs['configuration'] = encrypt_field(credential, 'configuration') + credential.inputs['gce_credentials'] = encrypt_field(credential, 'gce_credentials') + job.credentials.add(credential) + + env = {} + safe_env = {} + credential.credential_type.inject_credential(credential, env, safe_env, [], private_data_dir) + + local_path = to_host_path(env['TF_BACKEND_CONFIG_FILE'], private_data_dir) + config = open(local_path, 'r').read() + assert config == hcl_config + + credentials_path = to_host_path(env['GOOGLE_BACKEND_CREDENTIALS'], private_data_dir) + credentials = open(credentials_path, 'r').read() + assert credentials == gce_backend_credentials + def test_custom_environment_injectors_with_jinja_syntax_error(self, private_data_dir, mock_me): some_cloud = CredentialType( kind='cloud', |