summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorabikouo <abikouo@redhat.com>2024-04-02 18:18:36 +0200
committerChris Meyers <chrismeyersfsu@users.noreply.github.com>2024-04-16 16:34:38 +0200
commit199507c6f1f5703a9e08bea7db6fb304dcd9e2b0 (patch)
tree67be494ff558bde215797b130e0cf197140a032f
parentUpdate LDAP/SAML config dump command (#15106) (diff)
downloadawx-199507c6f1f5703a9e08bea7db6fb304dcd9e2b0.tar.xz
awx-199507c6f1f5703a9e08bea7db6fb304dcd9e2b0.zip
Support Google credentials on Terraform credentials type
-rw-r--r--awx/main/models/credential/__init__.py8
-rw-r--r--awx/main/models/credential/injectors.py7
-rw-r--r--awx/main/models/inventory.py30
-rw-r--r--awx/main/tests/data/inventory/plugins/terraform/env.json2
-rw-r--r--awx/main/tests/unit/test_tasks.py38
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',