mirror of
https://github.com/ansible/awx.git
synced 2026-03-18 09:27:31 -02:30
Support Google credentials on Terraform credentials type
This commit is contained in:
@@ -1232,6 +1232,14 @@ ManagedCredentialType(
|
|||||||
'multiline': True,
|
'multiline': True,
|
||||||
'help_text': gettext_noop('Terraform backend config as Hashicorp configuration language.'),
|
'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'],
|
'required': ['configuration'],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -130,3 +130,10 @@ def terraform(cred, env, private_data_dir):
|
|||||||
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
|
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
|
||||||
f.write(cred.get_input('configuration'))
|
f.write(cred.get_input('configuration'))
|
||||||
env['TF_BACKEND_CONFIG_FILE'] = to_container_path(path, private_data_dir)
|
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)
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import os.path
|
|||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
import tempfile
|
||||||
|
import stat
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@@ -1638,17 +1640,39 @@ class satellite6(PluginFileInjector):
|
|||||||
|
|
||||||
class terraform(PluginFileInjector):
|
class terraform(PluginFileInjector):
|
||||||
plugin_name = 'terraform_state'
|
plugin_name = 'terraform_state'
|
||||||
base_injector = 'managed'
|
|
||||||
namespace = 'cloud'
|
namespace = 'cloud'
|
||||||
collection = 'terraform'
|
collection = 'terraform'
|
||||||
use_fqcn = True
|
use_fqcn = True
|
||||||
|
|
||||||
def inventory_as_dict(self, inventory_update, private_data_dir):
|
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 = 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
|
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):
|
class controller(PluginFileInjector):
|
||||||
plugin_name = 'tower' # TODO: relying on routing for now, update after EEs pick up revised collection
|
plugin_name = 'tower' # TODO: relying on routing for now, update after EEs pick up revised collection
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"TF_BACKEND_CONFIG_FILE": "{{ file_reference }}"
|
"GOOGLE_BACKEND_CREDENTIALS": "{{ file_reference }}"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1106,6 +1106,44 @@ class TestJobCredentials(TestJobExecution):
|
|||||||
config = open(local_path, 'r').read()
|
config = open(local_path, 'r').read()
|
||||||
assert config == hcl_config
|
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):
|
def test_custom_environment_injectors_with_jinja_syntax_error(self, private_data_dir, mock_me):
|
||||||
some_cloud = CredentialType(
|
some_cloud = CredentialType(
|
||||||
kind='cloud',
|
kind='cloud',
|
||||||
|
|||||||
Reference in New Issue
Block a user