Skip to content

Commit ed4c9a1

Browse files
authored
Merge pull request #5 from putmanoj/git-sync-templates
Sync Terraform Templates from git repo
2 parents dcacd45 + 421d6d3 commit ed4c9a1

File tree

5 files changed

+446
-10
lines changed

5 files changed

+446
-10
lines changed

app/models/manageiq/providers/embedded_terraform/automation_manager/configuration_script_source.rb

+95-10
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,32 @@ def self.display_name(number = 1)
55
n_('Repository (Embedded Terraform)', 'Repositories (Embedded Terraform)', number)
66
end
77

8+
private_class_method def self.queue_role
9+
"embedded_terraform"
10+
end
11+
812
def sync
913
update!(:status => "running")
1014

1115
transaction do
1216
current = configuration_script_payloads.index_by(&:name)
1317

14-
git_repository.update_repo
15-
git_repository.with_worktree do |worktree|
16-
worktree.ref = scm_branch
17-
worktree.blob_list.each do |filename|
18-
next if filename.start_with?(".") || !filename.end_with?(".tf")
18+
templates = find_templates_in_git_repo
19+
templates.each do |template_path, value|
20+
_log.info("Template: #{template_path} => #{value.to_json}")
1921

20-
payload = worktree.read_file(filename)
21-
found = current.delete(filename) || self.class.module_parent::Template.new(:configuration_script_source_id => id)
22+
found = current.delete(template_path) || self.class.module_parent::Template.new(:configuration_script_source_id => id)
23+
attrs = {
24+
:name => template_path,
25+
:manager_id => manager_id,
26+
:payload => value.to_json,
27+
:payload_type => 'json'
28+
}
2229

23-
found.update!(:name => filename, :manager_id => manager_id, :payload => payload, :payload_type => "json")
24-
end
30+
found.update!(attrs)
2531
end
2632

27-
current.values.each(&:destroy)
33+
current.each_value(&:destroy)
2834
configuration_script_payloads.reload
2935
end
3036

@@ -33,4 +39,83 @@ def sync
3339
update!(:status => "error", :last_updated_on => Time.zone.now, :last_update_error => error)
3440
raise error
3541
end
42+
43+
# Return Template name, using relative_path's basename prefix,
44+
# and suffix with git-repo url details
45+
# 'basename(branch_name):hostname/path/relative_path_parent)'
46+
# eg.
47+
# https://github.ibm.com/manoj-puthran/sample-scripts/tree/v2.0/terraform/templates/hello-world
48+
# is converted as
49+
# "hello-world(v2.0):github.ibm.com/manoj-puthran/sample-scripts/terraform/templates"
50+
def self.template_name_from_git_repo_url(git_repo_url, branch_name, relative_path)
51+
temp_url = git_repo_url
52+
# URI library cannot handle git urls, so just convert it to a standard url.
53+
temp_url = temp_url.sub(':', '/').sub('git@', 'https://') if temp_url.start_with?('git@')
54+
temp_uri = URI.parse(temp_url)
55+
hostname = temp_uri.hostname
56+
path = temp_uri.path
57+
path = path[0...-4] if path.end_with?('.git')
58+
path = path[0...-5] if path.end_with?('.git/')
59+
# if template dir is root, then use repo name as basename
60+
if relative_path == '.'
61+
basename = File.basename(path)
62+
parent_path = ''
63+
else
64+
basename = File.basename(relative_path)
65+
parent_path = File.dirname(relative_path)
66+
end
67+
"#{basename}(#{branch_name}):#{hostname}#{path}/#{parent_path}"
68+
end
69+
70+
private
71+
72+
# Find Terraform Templates(dir) in the git repo.
73+
# Iterate through git repo worktree, and collate all terraform template dir's (dirs with .tf or .tf.json files).
74+
#
75+
# Returns [Hash] of template directories and files within it.
76+
def find_templates_in_git_repo
77+
template_dirs = {}
78+
79+
# checkout files to temp dir, we need for parsing input/output vars
80+
git_checkout_tempdir = Dir.mktmpdir("terraform-git")
81+
checkout_git_repository(git_checkout_tempdir)
82+
83+
# traverse through files in git-worktree
84+
git_repository.with_worktree do |worktree|
85+
worktree.ref = scm_branch
86+
87+
# Find all dir's with .tf/.tf.json files
88+
worktree.blob_list.each do |filepath|
89+
next unless filepath.end_with?(".tf", ".tf.json")
90+
91+
parent_dir = File.dirname(filepath)
92+
name = self.class.template_name_from_git_repo_url(
93+
git_repository.url, scm_branch, parent_dir
94+
)
95+
96+
next if template_dirs.key?(name)
97+
98+
full_path = File.join(git_checkout_tempdir, parent_dir)
99+
_log.debug("Local full path : #{full_path}")
100+
files = Dir.children(full_path)
101+
102+
# TODO: add parsing for input/output vars
103+
input_vars = nil
104+
output_vars = nil
105+
106+
template_dirs[name] = {
107+
:relative_path => parent_dir,
108+
:files => files,
109+
:input_vars => input_vars,
110+
:output_vars => output_vars
111+
}
112+
_log.debug("=== Add Template:#{name}")
113+
end
114+
end
115+
116+
template_dirs
117+
ensure
118+
# cleanup temp git directory
119+
FileUtils.rm_rf(git_checkout_tempdir) if git_checkout_tempdir
120+
end
36121
end

spec/factories/authentication.rb

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FactoryBot.define do
2+
factory :embedded_terraform_credential,
3+
:parent => :embedded_automation_manager_authentication,
4+
:class => "ManageIQ::Providers::EmbeddedTerraform::AutomationManager::Credential"
5+
6+
factory :embedded_terraform_scm_credential,
7+
:parent => :embedded_terraform_credential,
8+
:class => "ManageIQ::Providers::EmbeddedTerraform::AutomationManager::ScmCredential"
9+
end
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FactoryBot.define do
2+
# Leaf classes for automation_manager
3+
factory :embedded_automation_manager_terraform,
4+
:aliases => ["manageiq/providers/embedded_terraform/automation_manager"],
5+
:class => "ManageIQ::Providers::EmbeddedTerraform::AutomationManager",
6+
:parent => :embedded_automation_manager do
7+
end
8+
end

0 commit comments

Comments
 (0)