terraspace 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +42 -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/core.rb +8 -0
- data/lib/terraspace/logger.rb +3 -2
- data/lib/terraspace/plugin/expander/interface.rb +5 -8
- 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/core.rb
CHANGED
@@ -18,6 +18,14 @@ module Terraspace
|
|
18
18
|
ENV['TS_EXTRA'] unless ENV['TS_EXTRA'].blank?
|
19
19
|
end
|
20
20
|
|
21
|
+
def project
|
22
|
+
if ENV['TS_PROJECT'].blank?
|
23
|
+
config.cloud.project
|
24
|
+
else
|
25
|
+
ENV['TS_PROJECT']
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
21
29
|
@@root = nil
|
22
30
|
def root
|
23
31
|
@@root ||= ENV['TS_ROOT'] || Dir.pwd
|
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
|
@@ -96,10 +96,11 @@ module Terraspace::Plugin::Expander
|
|
96
96
|
@mod.name
|
97
97
|
end
|
98
98
|
|
99
|
-
def app;
|
100
|
-
def
|
101
|
-
def
|
102
|
-
def
|
99
|
+
def app; Terraspace.app ; end
|
100
|
+
def env; Terraspace.env ; end
|
101
|
+
def extra; Terraspace.extra ; end
|
102
|
+
def project; Terraspace.project ; end
|
103
|
+
def role; Terraspace.role ; end
|
103
104
|
|
104
105
|
def type_instance
|
105
106
|
[type, instance].reject { |s| s.blank? }.join('-')
|
@@ -114,10 +115,6 @@ module Terraspace::Plugin::Expander
|
|
114
115
|
Terraspace.cache_root
|
115
116
|
end
|
116
117
|
|
117
|
-
def project
|
118
|
-
Terraspace.config.cloud.project
|
119
|
-
end
|
120
|
-
|
121
118
|
# So default config works:
|
122
119
|
# config.cache_dir = ":REGION/:ENV/:BUILD_DIR"
|
123
120
|
# For when folks configure it with the http backend for non-cloud providers
|
@@ -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.0
|
4
|
+
version: 2.1.0
|
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-11 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
|