terraspace 2.0.2 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.cody/README.md +1 -1
- data/.cody/all/project.rb +4 -0
- data/.cody/aws/project.rb +4 -0
- data/.cody/azurerm/project.rb +4 -0
- data/.cody/google/project.rb +4 -0
- data/.cody/none/project.rb +4 -0
- data/.cody/shared/script/install/infracost.sh +6 -0
- data/.cody/shared/script/install/terraform.sh +2 -2
- data/.cody/shared/script/install.sh +1 -0
- data/.github/FUNDING.yml +1 -0
- data/.pipedream/README.md +1 -1
- data/.pipedream/pipeline.rb +15 -8
- data/CHANGELOG.md +16 -0
- data/lib/templates/base/project/Gemfile.tt +5 -0
- data/lib/templates/base/project/config/app.rb +6 -2
- data/lib/templates/plugin/ci/CHANGELOG.md.tt +1 -1
- data/lib/templates/plugin/ci/lib/%gem_name%/vars.rb.tt +1 -1
- data/lib/terraspace/app.rb +16 -0
- data/lib/terraspace/cli/base.rb +1 -0
- data/lib/terraspace/cli/commander.rb +2 -1
- data/lib/terraspace/cli/concerns/plan_path.rb +1 -1
- data/lib/terraspace/cli/down.rb +43 -6
- data/lib/terraspace/cli/logs/concern.rb +1 -1
- data/lib/terraspace/cli/new/plugin/ci.rb +1 -4
- data/lib/terraspace/cli/plan.rb +66 -2
- data/lib/terraspace/cli/up.rb +65 -11
- data/lib/terraspace/cloud/api/cani.rb +15 -9
- data/lib/terraspace/cloud/api/concern.rb +0 -1
- data/lib/terraspace/cloud/api/http_methods.rb +7 -2
- data/lib/terraspace/cloud/api.rb +29 -5
- data/lib/terraspace/cloud/base.rb +16 -29
- data/lib/terraspace/cloud/ci.rb +1 -8
- data/lib/terraspace/cloud/comment.rb +28 -0
- data/lib/terraspace/cloud/context.rb +1 -0
- data/lib/terraspace/cloud/cost/infracost.rb +80 -0
- data/lib/terraspace/cloud/cost.rb +68 -0
- data/lib/terraspace/cloud/git.rb +0 -0
- data/lib/terraspace/cloud/plan.rb +33 -15
- data/lib/terraspace/cloud/stream.rb +113 -0
- data/lib/terraspace/cloud/streamer.rb +9 -0
- data/lib/terraspace/cloud/update.rb +19 -19
- data/lib/terraspace/cloud/{folder → upload}/base.rb +2 -2
- data/lib/terraspace/cloud/{folder → upload}/package.rb +2 -2
- data/lib/terraspace/cloud/{folder → upload}/tidy.rb +1 -1
- data/lib/terraspace/cloud/upload.rb +53 -0
- data/lib/terraspace/cloud/vcs/base.rb +6 -0
- data/lib/terraspace/cloud/vcs/ci_env.rb +15 -0
- data/lib/terraspace/cloud/vcs/commenter.rb +75 -0
- data/lib/terraspace/cloud/vcs/interface.rb +14 -0
- data/lib/terraspace/cloud/vcs/local_env.rb +25 -0
- data/lib/terraspace/cloud/{ci/vcs → vcs/local_git}/base.rb +6 -3
- data/lib/terraspace/cloud/vcs/local_git/bitbucket.rb +17 -0
- data/lib/terraspace/cloud/vcs/local_git/github.rb +17 -0
- data/lib/terraspace/cloud/vcs/local_git/gitlab.rb +17 -0
- data/lib/terraspace/cloud/{ci/manual.rb → vcs/local_git.rb} +18 -10
- data/lib/terraspace/cloud/vcs.rb +21 -0
- data/lib/terraspace/compiler/strategy/tfvar/layer.rb +1 -1
- data/lib/terraspace/logger.rb +3 -2
- data/lib/terraspace/shell/error.rb +1 -1
- data/lib/terraspace/terraform/runner.rb +4 -22
- data/lib/terraspace/util/popen.rb +67 -0
- data/lib/terraspace/version.rb +1 -1
- metadata +26 -23
- data/lib/templates/plugin/ci/lib/%gem_name%/pr.rb.tt +0 -15
- data/lib/terraspace/cloud/api/concern/record.rb +0 -18
- data/lib/terraspace/cloud/ci/generic.rb +0 -25
- data/lib/terraspace/cloud/ci/vcs/bitbucket.rb +0 -11
- data/lib/terraspace/cloud/ci/vcs/github.rb +0 -11
- data/lib/terraspace/cloud/ci/vcs/gitlab.rb +0 -11
- data/lib/terraspace/cloud/ci/vcs.rb +0 -18
- data/lib/terraspace/cloud/folder/uploader.rb +0 -37
- data/lib/terraspace/cloud/folder.rb +0 -11
- data/lib/terraspace/terraform/ihooks/after/apply.rb +0 -8
- data/lib/terraspace/terraform/ihooks/after/destroy.rb +0 -8
- data/lib/terraspace/terraform/ihooks/after/plan.rb +0 -46
- data/lib/terraspace/terraform/ihooks/base.rb +0 -17
- data/lib/terraspace/terraform/ihooks/before/apply.rb +0 -8
- data/lib/terraspace/terraform/ihooks/before/destroy.rb +0 -8
- data/lib/terraspace/terraform/ihooks/before/plan.rb +0 -20
@@ -0,0 +1,53 @@
|
|
1
|
+
module Terraspace::Cloud
|
2
|
+
class Upload < Base
|
3
|
+
def create(data) # data: {stream_id:, type: }
|
4
|
+
zip_path = Package.new(@options.merge(data)).build
|
5
|
+
upload = create_upload(data)
|
6
|
+
upload_project(upload, zip_path)
|
7
|
+
upload
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def create_upload(params)
|
12
|
+
upload = api.create_upload(params)
|
13
|
+
if errors?(upload)
|
14
|
+
error_message(upload)
|
15
|
+
exit 1 # Consider: raise exception can rescue higher up
|
16
|
+
else
|
17
|
+
upload
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def upload_project(upload, path, retries=0)
|
22
|
+
url = upload['data']['attributes']['url']
|
23
|
+
uri = URI.parse(url)
|
24
|
+
object_content = IO.read(path)
|
25
|
+
sleep 2
|
26
|
+
resp = Net::HTTP.start(uri.host) do |http|
|
27
|
+
http.send_request(
|
28
|
+
'PUT',
|
29
|
+
uri.request_uri,
|
30
|
+
object_content,
|
31
|
+
'content-type' => ''
|
32
|
+
)
|
33
|
+
end
|
34
|
+
return if resp.code =~ /^20/
|
35
|
+
|
36
|
+
log_errors(resp.body, :debug)
|
37
|
+
if resp.body.include?('expired')
|
38
|
+
if retries >= 10 # 15m * 10 = 150m = 2.5h
|
39
|
+
log_errors(resp.body, :info)
|
40
|
+
exit 1
|
41
|
+
end
|
42
|
+
logger.debug("Retrying upload")
|
43
|
+
upload = create_upload(upload_id: upload['data']['id'])
|
44
|
+
upload_project(upload, path, retries+1)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def log_errors(body, level=:debug)
|
49
|
+
logger.send(level, "ERROR: Uploader uploading code")
|
50
|
+
logger.send(level, "resp body #{body}")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Terraspace::Cloud::Vcs
|
2
|
+
class CiEnv
|
3
|
+
extend Memoist
|
4
|
+
include Terraspace::Util::Logging
|
5
|
+
|
6
|
+
def vars
|
7
|
+
klass = Terraspace::Cloud::Ci.detect
|
8
|
+
if klass
|
9
|
+
klass.new.vars.compact # remove items with nil values
|
10
|
+
else
|
11
|
+
{}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class Terraspace::Cloud::Vcs
|
2
|
+
module Commenter
|
3
|
+
extend Memoist
|
4
|
+
|
5
|
+
# record is plan or update
|
6
|
+
def pr_comment(record, cost)
|
7
|
+
return unless able_to_comment?
|
8
|
+
|
9
|
+
resp = cloud_comment.get(record, cost)
|
10
|
+
body = resp['data']['attributes']['body'] if resp
|
11
|
+
if body
|
12
|
+
vcs.comment(body)
|
13
|
+
else
|
14
|
+
logger.info "WARN: Unable to post a PR comment"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def cloud_comment
|
19
|
+
Terraspace::Cloud::Comment.new(@options.merge(stack: @mod.name, kind: kind))
|
20
|
+
end
|
21
|
+
memoize :cloud_comment
|
22
|
+
|
23
|
+
def vcs
|
24
|
+
# IE: TerraspaceVcsGithub::Interface.new
|
25
|
+
Terraspace::Cloud::Vcs.detect(full_repo: vcs_vars[:full_repo], pr_number: vcs_vars[:pr_number])
|
26
|
+
end
|
27
|
+
memoize :vcs
|
28
|
+
|
29
|
+
#
|
30
|
+
# full_repo # env or .git * min required for pr url
|
31
|
+
# host # env or .git * min required for pr url
|
32
|
+
# branch_name # env or .git
|
33
|
+
# sha # env or .git
|
34
|
+
# dirty # env or .git
|
35
|
+
# pr_number # env * min required for pr url
|
36
|
+
#
|
37
|
+
# commit_message # env
|
38
|
+
# build_system # env
|
39
|
+
# build_id # env
|
40
|
+
# build_number # env
|
41
|
+
# build_type # env
|
42
|
+
#
|
43
|
+
# build_url
|
44
|
+
# commit_url
|
45
|
+
# branch_url
|
46
|
+
# pr_url
|
47
|
+
#
|
48
|
+
def vcs_vars
|
49
|
+
ci_env = CiEnv.new
|
50
|
+
local_git = LocalGit.new
|
51
|
+
local_env = LocalEnv.new
|
52
|
+
vars = local_git.vars.merge(ci_env.vars).merge(local_env.vars)
|
53
|
+
finalize_vars(local_git, vars)
|
54
|
+
end
|
55
|
+
memoize :vcs_vars
|
56
|
+
|
57
|
+
# finalize branch_url since info is set from multiple layers
|
58
|
+
def finalize_vars(local_git, vars)
|
59
|
+
if local_git.vcs_class # IE: LocalGit::Github
|
60
|
+
vars[:branch_url] ||= local_git.vcs_class.new(vars).branch_url # IE: LocalGit::Github#branch_url
|
61
|
+
end
|
62
|
+
vars
|
63
|
+
end
|
64
|
+
|
65
|
+
def able_to_comment?
|
66
|
+
!!(vcs && vcs_vars[:full_repo] && vcs_vars[:pr_number])
|
67
|
+
end
|
68
|
+
|
69
|
+
# stored on cloud: kind can be apply or destroy. its extra info
|
70
|
+
def kind
|
71
|
+
is_destroy = Terraspace.command?("down") || @options[:args]&.include?('--destroy') || @options[:destroy]
|
72
|
+
is_destroy ? "destroy" : "apply"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Terraspace::Cloud::Vcs
|
2
|
+
module Interface
|
3
|
+
extend Memoist
|
4
|
+
include Terraspace::Util::Logging
|
5
|
+
|
6
|
+
MARKER = "<!-- terraspace marker -->"
|
7
|
+
|
8
|
+
attr_reader :full_repo, :pr_number
|
9
|
+
def initialize(options={})
|
10
|
+
@full_repo = options[:full_repo]
|
11
|
+
@pr_number = options[:pr_number]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Terraspace::Cloud::Vcs
|
2
|
+
class LocalEnv < Base
|
3
|
+
def vars
|
4
|
+
# Do not set any default values. These take highest precedence and will override LocalGit and CiVars
|
5
|
+
{
|
6
|
+
host: ENV['TS_VCS_HOST'] || ENV['VCS_HOST'] || ENV['GIT_HOST'],
|
7
|
+
full_repo: ENV['TS_VCS_REPO'] || ENV['VCS_REPO'] || ENV['GIT_REPO'],
|
8
|
+
branch_name: ENV['TS_VCS_BRANCH'],
|
9
|
+
# urls
|
10
|
+
commit_url: ENV['TS_VCS_COMMIT_URL'],
|
11
|
+
branch_url: ENV['TS_VCS_BRANCH_URL'],
|
12
|
+
pr_url: ENV['TS_VCS_PR_URL'],
|
13
|
+
build_url: ENV['TS_VCS_BUILD_URL'],
|
14
|
+
# additional properties
|
15
|
+
build_type: ENV['TS_VCS_BUILD_TYPE'],
|
16
|
+
# pr_number: ENV['TS_VCS_PR_NUMBER'] || ENV['PR_NUMBER'] || ENV['MR_NUMBER'], # handle in LocalGit::Base so can compute pr_url
|
17
|
+
sha: ENV['TS_VCS_SHA'],
|
18
|
+
# additional properties
|
19
|
+
commit_message: ENV['TS_VCS_COMMIT_MESSAGE'],
|
20
|
+
build_id: ENV['TS_VCS_BUILD_ID'],
|
21
|
+
build_number: ENV['TS_VCS_BUILD_NUMBER'],
|
22
|
+
}.compact # remove items with nil values
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Terraspace::Cloud::
|
1
|
+
class Terraspace::Cloud::Vcs::LocalGit
|
2
2
|
class Base
|
3
3
|
extend Memoist
|
4
4
|
|
@@ -10,11 +10,14 @@ class Terraspace::Cloud::Ci::Vcs
|
|
10
10
|
{
|
11
11
|
commit_url: commit_url, # implemented by subclass
|
12
12
|
branch_url: branch_url, # implemented by subclass
|
13
|
+
# pr_url handled when PR_NUMBER set by user outside of ci env. ci plugin pr_url takes higher precedence though
|
14
|
+
pr_number: pr_number,
|
15
|
+
pr_url: pr_url,
|
13
16
|
}
|
14
17
|
end
|
15
18
|
|
16
|
-
def
|
17
|
-
|
19
|
+
def pr_number
|
20
|
+
ENV['TS_VCS_PR_NUMBER'] || ENV['PR_NUMBER'] || ENV['MR_NUMBER']
|
18
21
|
end
|
19
22
|
|
20
23
|
class << self
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Terraspace::Cloud::Vcs::LocalGit
|
2
|
+
class Bitbucket < Base
|
3
|
+
def commit_url
|
4
|
+
"#{host}/#{full_repo}/commits/#{sha}" if sha
|
5
|
+
end
|
6
|
+
|
7
|
+
def branch_url
|
8
|
+
"#{host}/#{full_repo}/branch/#{branch_name}" if branch_name
|
9
|
+
end
|
10
|
+
|
11
|
+
# Also computed in ci plugins which detects it from the ci env.
|
12
|
+
# Also handling here for case when user provides PR_NUMBER and GIT_REPO outside of normal CI env.
|
13
|
+
def pr_url
|
14
|
+
"#{host}/#{full_repo}/pull-requests/#{pr_number}" if pr_number
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Terraspace::Cloud::Vcs::LocalGit
|
2
|
+
class Github < Base
|
3
|
+
def commit_url
|
4
|
+
"#{host}/#{full_repo}/commits/#{sha}" if sha
|
5
|
+
end
|
6
|
+
|
7
|
+
def branch_url
|
8
|
+
"#{host}/#{full_repo}/tree/#{branch_name}" if branch_name
|
9
|
+
end
|
10
|
+
|
11
|
+
# Also computed in ci plugins which detects it from the ci env.
|
12
|
+
# Also handling here for case when user provides PR_NUMBER and GIT_REPO outside of normal CI env.
|
13
|
+
def pr_url
|
14
|
+
"#{host}/#{full_repo}/pull/#{pr_number}" if pr_number
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Terraspace::Cloud::Vcs::LocalGit
|
2
|
+
class Gitlab < Base
|
3
|
+
def commit_url
|
4
|
+
"#{host}/#{full_repo}/-/commits/#{sha}" if sha
|
5
|
+
end
|
6
|
+
|
7
|
+
def branch_url
|
8
|
+
"#{host}/#{full_repo}/-/tree/#{branch_name}" if branch_name
|
9
|
+
end
|
10
|
+
|
11
|
+
# Also computed in ci plugins which detects it from the ci env.
|
12
|
+
# Also handling here for case when user provides PR_NUMBER and GIT_REPO outside of normal CI env.
|
13
|
+
def pr_url
|
14
|
+
"#{host}/#{full_repo}/-/merge_requests/#{pr_number}" if pr_number
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,17 +1,23 @@
|
|
1
|
-
class Terraspace::Cloud::
|
2
|
-
class
|
3
|
-
extend Memoist
|
4
|
-
include Terraspace::Util::Logging
|
5
|
-
|
1
|
+
class Terraspace::Cloud::Vcs
|
2
|
+
class LocalGit < Base
|
6
3
|
def vars
|
7
4
|
if git_repo? && git_installed?
|
8
|
-
|
5
|
+
provider_vars = vcs_class ? vcs_class.new(base_vars).vars : {}
|
6
|
+
base_vars.merge(provider_vars).compact # remove items with nil values
|
9
7
|
else
|
10
8
|
{ build_system: "manual" }
|
11
9
|
end
|
12
10
|
end
|
13
11
|
|
14
|
-
def
|
12
|
+
def vcs_class
|
13
|
+
case host
|
14
|
+
when /github/ then Github
|
15
|
+
when /gitlab/ then Gitlab
|
16
|
+
when /bitbucket/ then Bitbucket
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def base_vars
|
15
21
|
{
|
16
22
|
build_system: "manual", # required
|
17
23
|
host: host,
|
@@ -19,8 +25,8 @@ class Terraspace::Cloud::Ci
|
|
19
25
|
branch_name: branch_name,
|
20
26
|
sha: sha,
|
21
27
|
dirty: dirty?,
|
22
|
-
# commit_url: commit_url, # provided by
|
23
|
-
# branch_url: branch_url, # provided by
|
28
|
+
# commit_url: commit_url, # provided by provider vars
|
29
|
+
# branch_url: branch_url, # provided by provider vars
|
24
30
|
}
|
25
31
|
end
|
26
32
|
|
@@ -46,7 +52,9 @@ class Terraspace::Cloud::Ci
|
|
46
52
|
# git@bitbucket.org: => https://bitbucket.org/
|
47
53
|
# git@gitlab.com: => https://gitlab.com/
|
48
54
|
def git_url
|
49
|
-
|
55
|
+
remotes = git("remote").strip.split("\n")
|
56
|
+
remote_name = remotes.size == 1 ? remotes[0] : "origin"
|
57
|
+
out = git "config --get remote.#{remote_name}.url"
|
50
58
|
out.sub(/\.git/,'').sub(/^git@/,'https://').sub(/\.(.*):/,'.\1/')
|
51
59
|
end
|
52
60
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Terraspace::Cloud
|
2
|
+
class Vcs
|
3
|
+
class << self
|
4
|
+
@@name = nil
|
5
|
+
def register(options={})
|
6
|
+
@@name = options[:name]
|
7
|
+
end
|
8
|
+
|
9
|
+
# IE: TerraspaceVcsGithub::Interface.new
|
10
|
+
def detect(options)
|
11
|
+
name = detect_name
|
12
|
+
"TerraspaceVcs#{name.camelize}::Interface".constantize.new(options) if name
|
13
|
+
end
|
14
|
+
|
15
|
+
def detect_name
|
16
|
+
# allow user to override vcs.name
|
17
|
+
Terraspace.config.cloud.vcs.name || @@name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -41,7 +41,7 @@ class Terraspace::Compiler::Strategy::Tfvar
|
|
41
41
|
def paths
|
42
42
|
project_paths = full_paths(project_tfvars_dir)
|
43
43
|
stack_paths = full_paths(stack_tfvars_dir)
|
44
|
-
paths = project_paths + stack_paths
|
44
|
+
paths = (project_paths + stack_paths).uniq
|
45
45
|
show_layers(paths)
|
46
46
|
paths.select do |path|
|
47
47
|
File.exist?(path)
|
data/lib/terraspace/logger.rb
CHANGED
@@ -14,7 +14,7 @@ module Terraspace
|
|
14
14
|
else
|
15
15
|
super # use the configured formatter
|
16
16
|
end
|
17
|
-
out = line =~ /\n$/ ? line : "#{line}\n"
|
17
|
+
out = line.force_encoding('UTF-8') =~ /\n$/ ? line : "#{line}\n"
|
18
18
|
@@buffer << out
|
19
19
|
out
|
20
20
|
end
|
@@ -45,7 +45,8 @@ module Terraspace
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def logs
|
48
|
-
|
48
|
+
# force_encoding https://jch.github.io/posts/2013-03-05-ruby-incompatible-encoding.html
|
49
|
+
@@buffer.map { |s| s.force_encoding('UTF-8') }.join('')
|
49
50
|
end
|
50
51
|
|
51
52
|
# for test framework
|
@@ -4,7 +4,7 @@ module Terraspace::Terraform
|
|
4
4
|
include Terraspace::Hooks::Concern
|
5
5
|
include Terraspace::Util
|
6
6
|
|
7
|
-
attr_reader :name
|
7
|
+
attr_reader :name, :shell_exception
|
8
8
|
def initialize(name, options={})
|
9
9
|
@name = name
|
10
10
|
super(options)
|
@@ -14,12 +14,7 @@ module Terraspace::Terraform
|
|
14
14
|
time_took do
|
15
15
|
terraform(name, args)
|
16
16
|
end
|
17
|
-
|
18
|
-
run_internal_hook(:after, name) # always run so plan and apply get saved to tsc
|
19
|
-
if @shell_error
|
20
|
-
logger.error @shell_error.message.color(:red)
|
21
|
-
exit 1 if name == "plan" && Terraspace.command?("up")
|
22
|
-
end
|
17
|
+
@success
|
23
18
|
end
|
24
19
|
|
25
20
|
# default at end in case of redirection. IE: terraform output > /path
|
@@ -51,15 +46,14 @@ module Terraspace::Terraform
|
|
51
46
|
|
52
47
|
params = args.flatten.join(' ')
|
53
48
|
command = "terraform #{name} #{params}".squish
|
54
|
-
@
|
49
|
+
@shell_exception = nil
|
55
50
|
run_hooks("terraform.rb", name) do
|
56
51
|
Backend.new(@mod).create
|
57
|
-
run_internal_hook(:before, name)
|
58
52
|
begin
|
59
53
|
Terraspace::Shell.new(@mod, command, @options.merge(env: custom.env_vars)).run
|
60
54
|
@success = true
|
61
55
|
rescue Terraspace::ShellError => exception
|
62
|
-
@
|
56
|
+
@shell_exception = exception
|
63
57
|
@success = false
|
64
58
|
end
|
65
59
|
end
|
@@ -73,18 +67,6 @@ module Terraspace::Terraform
|
|
73
67
|
end
|
74
68
|
end
|
75
69
|
|
76
|
-
def run_internal_hook(type, name)
|
77
|
-
begin
|
78
|
-
class_name = "Terraspace::Terraform::Ihooks::#{type.to_s.classify}::#{name.classify}"
|
79
|
-
klass = class_name.constantize
|
80
|
-
rescue NameError => e
|
81
|
-
logger.debug "DEBUG: #{e.class} #{e.message}".color(:red)
|
82
|
-
return
|
83
|
-
end
|
84
|
-
ihook = klass.new(name, @options.merge(success: @success))
|
85
|
-
ihook.run
|
86
|
-
end
|
87
|
-
|
88
70
|
@@current_dir_message_shown = false
|
89
71
|
def current_dir_message
|
90
72
|
return if @@current_dir_message_shown
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module Terraspace::Util
|
4
|
+
module Popen
|
5
|
+
include Logging
|
6
|
+
|
7
|
+
# Similar to Terraspace::Shell#popen3
|
8
|
+
# More generalized. Useful for plugins
|
9
|
+
def popen(command, options={})
|
10
|
+
Open3.popen3(command) do |stdin, stdout, stderr, wait_thread|
|
11
|
+
handle_streams(stdin, stdout, stderr, options)
|
12
|
+
status = wait_thread.value.exitstatus
|
13
|
+
unless status == 0
|
14
|
+
logger.error "Error running command #{command}".color(:red)
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
BLOCK_SIZE = Integer(ENV['TS_BUFFER_BLOCK_SIZE'] || 102400)
|
21
|
+
def handle_streams(stdin, stdout, stderr, options)
|
22
|
+
files = [stdout, stderr]
|
23
|
+
until all_eof?(files) do
|
24
|
+
ready = IO.select(files)
|
25
|
+
next unless ready
|
26
|
+
|
27
|
+
readable = ready[0]
|
28
|
+
readable.each do |f|
|
29
|
+
buffer = f.read_nonblock(BLOCK_SIZE, exception: false)
|
30
|
+
next unless buffer
|
31
|
+
|
32
|
+
lines = buffer.split("\n")
|
33
|
+
lines.each do |line|
|
34
|
+
if f.fileno == stdout.fileno
|
35
|
+
handle_stdout(line, options)
|
36
|
+
else
|
37
|
+
handle_stderr(line, options)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def handle_stdout(line, options={})
|
45
|
+
newline = options[:newline].nil? ? true : options[:newline]
|
46
|
+
filter = options[:filter]
|
47
|
+
|
48
|
+
# Terraspace logger has special stdout method so original terraform output
|
49
|
+
# can be piped to jq. IE:
|
50
|
+
# terraspace show demo --json | jq
|
51
|
+
if logger.respond_to?(:stdout) && !options[:log_to_stderr]
|
52
|
+
logger.stdout(line, newline: newline) unless line.include?(filter)
|
53
|
+
else
|
54
|
+
logger.info(line) unless line.include?(filter)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def handle_stderr(line, options={})
|
59
|
+
logger.error(line) unless line.include?(options[:filter])
|
60
|
+
end
|
61
|
+
|
62
|
+
def all_eof?(files)
|
63
|
+
files.find { |f| !f.eof }.nil?
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
data/lib/terraspace/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: terraspace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tung Nguyen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -382,12 +382,14 @@ files:
|
|
382
382
|
- ".cody/none/iam_role.rb"
|
383
383
|
- ".cody/none/project.rb"
|
384
384
|
- ".cody/shared/script/install.sh"
|
385
|
+
- ".cody/shared/script/install/infracost.sh"
|
385
386
|
- ".cody/shared/script/install/terraform.sh"
|
386
387
|
- ".cody/shared/script/install/terraspace.sh"
|
387
388
|
- ".cody/shared/script/update/gemfile.sh"
|
388
389
|
- ".cody/unit/bin/build.sh"
|
389
390
|
- ".cody/unit/buildspec.yml"
|
390
391
|
- ".cody/unit/project.rb"
|
392
|
+
- ".github/FUNDING.yml"
|
391
393
|
- ".github/ISSUE_TEMPLATE.md"
|
392
394
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
393
395
|
- ".github/ISSUE_TEMPLATE/documentation.md"
|
@@ -450,7 +452,6 @@ files:
|
|
450
452
|
- lib/templates/plugin/ci/lib/%gem_name%.rb.tt
|
451
453
|
- lib/templates/plugin/ci/lib/%gem_name%/autoloader.rb.tt
|
452
454
|
- lib/templates/plugin/ci/lib/%gem_name%/interface.rb.tt
|
453
|
-
- lib/templates/plugin/ci/lib/%gem_name%/pr.rb.tt
|
454
455
|
- lib/templates/plugin/ci/lib/%gem_name%/vars.rb.tt
|
455
456
|
- lib/templates/plugin/ci/lib/%gem_name%/version.rb.tt
|
456
457
|
- lib/templates/plugin/ci/spec/%gem_name%_spec.rb.tt
|
@@ -645,26 +646,34 @@ files:
|
|
645
646
|
- lib/terraspace/cloud/api/cani.rb
|
646
647
|
- lib/terraspace/cloud/api/concern.rb
|
647
648
|
- lib/terraspace/cloud/api/concern/errors.rb
|
648
|
-
- lib/terraspace/cloud/api/concern/record.rb
|
649
649
|
- lib/terraspace/cloud/api/http_methods.rb
|
650
650
|
- lib/terraspace/cloud/api/validate.rb
|
651
651
|
- lib/terraspace/cloud/base.rb
|
652
652
|
- lib/terraspace/cloud/ci.rb
|
653
|
-
- lib/terraspace/cloud/
|
654
|
-
- lib/terraspace/cloud/ci/manual.rb
|
655
|
-
- lib/terraspace/cloud/ci/vcs.rb
|
656
|
-
- lib/terraspace/cloud/ci/vcs/base.rb
|
657
|
-
- lib/terraspace/cloud/ci/vcs/bitbucket.rb
|
658
|
-
- lib/terraspace/cloud/ci/vcs/github.rb
|
659
|
-
- lib/terraspace/cloud/ci/vcs/gitlab.rb
|
653
|
+
- lib/terraspace/cloud/comment.rb
|
660
654
|
- lib/terraspace/cloud/context.rb
|
661
|
-
- lib/terraspace/cloud/
|
662
|
-
- lib/terraspace/cloud/
|
663
|
-
- lib/terraspace/cloud/
|
664
|
-
- lib/terraspace/cloud/folder/tidy.rb
|
665
|
-
- lib/terraspace/cloud/folder/uploader.rb
|
655
|
+
- lib/terraspace/cloud/cost.rb
|
656
|
+
- lib/terraspace/cloud/cost/infracost.rb
|
657
|
+
- lib/terraspace/cloud/git.rb
|
666
658
|
- lib/terraspace/cloud/plan.rb
|
659
|
+
- lib/terraspace/cloud/stream.rb
|
660
|
+
- lib/terraspace/cloud/streamer.rb
|
667
661
|
- lib/terraspace/cloud/update.rb
|
662
|
+
- lib/terraspace/cloud/upload.rb
|
663
|
+
- lib/terraspace/cloud/upload/base.rb
|
664
|
+
- lib/terraspace/cloud/upload/package.rb
|
665
|
+
- lib/terraspace/cloud/upload/tidy.rb
|
666
|
+
- lib/terraspace/cloud/vcs.rb
|
667
|
+
- lib/terraspace/cloud/vcs/base.rb
|
668
|
+
- lib/terraspace/cloud/vcs/ci_env.rb
|
669
|
+
- lib/terraspace/cloud/vcs/commenter.rb
|
670
|
+
- lib/terraspace/cloud/vcs/interface.rb
|
671
|
+
- lib/terraspace/cloud/vcs/local_env.rb
|
672
|
+
- lib/terraspace/cloud/vcs/local_git.rb
|
673
|
+
- lib/terraspace/cloud/vcs/local_git/base.rb
|
674
|
+
- lib/terraspace/cloud/vcs/local_git/bitbucket.rb
|
675
|
+
- lib/terraspace/cloud/vcs/local_git/github.rb
|
676
|
+
- lib/terraspace/cloud/vcs/local_git/gitlab.rb
|
668
677
|
- lib/terraspace/command.rb
|
669
678
|
- lib/terraspace/compiler/basename.rb
|
670
679
|
- lib/terraspace/compiler/cleaner.rb
|
@@ -773,13 +782,6 @@ files:
|
|
773
782
|
- lib/terraspace/terraform/args/pass.rb
|
774
783
|
- lib/terraspace/terraform/args/shorthands.rb
|
775
784
|
- lib/terraspace/terraform/args/thor.rb
|
776
|
-
- lib/terraspace/terraform/ihooks/after/apply.rb
|
777
|
-
- lib/terraspace/terraform/ihooks/after/destroy.rb
|
778
|
-
- lib/terraspace/terraform/ihooks/after/plan.rb
|
779
|
-
- lib/terraspace/terraform/ihooks/base.rb
|
780
|
-
- lib/terraspace/terraform/ihooks/before/apply.rb
|
781
|
-
- lib/terraspace/terraform/ihooks/before/destroy.rb
|
782
|
-
- lib/terraspace/terraform/ihooks/before/plan.rb
|
783
785
|
- lib/terraspace/terraform/remote_state/fetcher.rb
|
784
786
|
- lib/terraspace/terraform/remote_state/marker/output.rb
|
785
787
|
- lib/terraspace/terraform/remote_state/marker/pretty_tracer.rb
|
@@ -802,6 +804,7 @@ files:
|
|
802
804
|
- lib/terraspace/tester/meta.rb
|
803
805
|
- lib/terraspace/util.rb
|
804
806
|
- lib/terraspace/util/logging.rb
|
807
|
+
- lib/terraspace/util/popen.rb
|
805
808
|
- lib/terraspace/util/pretty.rb
|
806
809
|
- lib/terraspace/util/sure.rb
|
807
810
|
- lib/terraspace/version.rb
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module <%= gem_class_name %>
|
2
|
-
class Pr
|
3
|
-
# Implement this method.
|
4
|
-
# Method should update existing comment instead of always creating new comment.
|
5
|
-
# Otherwise it gets noisy.
|
6
|
-
# Remember to also uncomment out the definition in
|
7
|
-
#
|
8
|
-
# <%= gem_class_name %>::Interface#comment(url)
|
9
|
-
#
|
10
|
-
# If CI system does not support PRs and comments. Can delete this class entirely.
|
11
|
-
#
|
12
|
-
def comment(url)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Terraspace::Cloud::Api::Concern
|
2
|
-
module Record
|
3
|
-
def load_record(result)
|
4
|
-
record = {}
|
5
|
-
data = result['data']
|
6
|
-
record['id'] = data['id']
|
7
|
-
record.merge!(data['attributes'])
|
8
|
-
record
|
9
|
-
end
|
10
|
-
|
11
|
-
def load_records(result)
|
12
|
-
result['data'].map do |item|
|
13
|
-
record = { id: item['id'] }
|
14
|
-
record.merge(item['attributes'])
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|