terraspace 0.3.6 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/README.md +57 -30
- data/lib/templates/base/project/README.md +1 -1
- data/lib/terraspace.rb +3 -1
- data/lib/terraspace/all/runner.rb +1 -0
- data/lib/terraspace/all/summary.rb +8 -1
- data/lib/terraspace/app.rb +9 -5
- data/lib/terraspace/builder.rb +10 -6
- data/lib/terraspace/cli.rb +12 -16
- data/lib/terraspace/cli/all.rb +6 -0
- data/lib/terraspace/cli/bundle.rb +2 -1
- data/lib/terraspace/cli/clean.rb +18 -6
- data/lib/terraspace/cli/clean/all.rb +18 -0
- data/lib/terraspace/cli/clean/base.rb +15 -0
- data/lib/terraspace/cli/clean/cache.rb +25 -0
- data/lib/terraspace/cli/{logs/tasks.rb → clean/logs.rb} +8 -9
- data/lib/terraspace/cli/cloud.rb +2 -0
- data/lib/terraspace/cli/help/all/init.md +33 -0
- data/lib/terraspace/cli/help/clean/all.md +10 -0
- data/lib/terraspace/cli/help/clean/cache.md +12 -0
- data/lib/terraspace/cli/help/clean/logs.md +17 -0
- data/lib/terraspace/cli/help/logs.md +48 -0
- data/lib/terraspace/cli/info.rb +12 -0
- data/lib/terraspace/cli/init.rb +3 -7
- data/lib/terraspace/cli/list.rb +2 -1
- data/lib/terraspace/cli/logs.rb +105 -10
- data/lib/terraspace/cli/{log → logs}/concern.rb +2 -1
- data/lib/terraspace/cli/new/helper.rb +9 -2
- data/lib/terraspace/dependency/helper/output.rb +1 -1
- data/lib/terraspace/hooks/builder.rb +52 -0
- data/lib/terraspace/hooks/concern.rb +9 -0
- data/lib/terraspace/{terraform/hooks → hooks}/dsl.rb +3 -2
- data/lib/terraspace/hooks/runner.rb +23 -0
- data/lib/terraspace/mod.rb +11 -2
- data/lib/terraspace/plugin/summary/interface.rb +3 -1
- data/lib/terraspace/shell.rb +5 -28
- data/lib/terraspace/shell/error.rb +46 -0
- data/lib/terraspace/terraform/args/custom.rb +1 -1
- data/lib/terraspace/terraform/args/default.rb +9 -19
- data/lib/terraspace/terraform/remote_state/output_proxy.rb +3 -3
- data/lib/terraspace/terraform/remote_state/{null_object.rb → unresolved.rb} +1 -1
- data/lib/terraspace/terraform/runner.rb +8 -21
- data/lib/terraspace/terraform/runner/retryer.rb +65 -0
- data/lib/terraspace/version.rb +1 -1
- data/spec/terraspace/{terraform/hooks → hooks}/builder_spec.rb +4 -5
- data/spec/terraspace/terraform/remote_state/output_proxy_spec.rb +3 -3
- data/terraspace.gemspec +1 -1
- metadata +23 -14
- data/lib/terraspace/cli/help/clean.md +0 -5
- data/lib/terraspace/cli/help/log.md +0 -48
- data/lib/terraspace/cli/log.rb +0 -112
- data/lib/terraspace/terraform/hooks/builder.rb +0 -40
@@ -0,0 +1,15 @@
|
|
1
|
+
class Terraspace::CLI::Clean
|
2
|
+
class Base
|
3
|
+
include Terraspace::Util::Logging
|
4
|
+
include Terraspace::Util::Sure
|
5
|
+
|
6
|
+
def initialize(options={})
|
7
|
+
@options = options
|
8
|
+
Terraspace.check_project!
|
9
|
+
end
|
10
|
+
|
11
|
+
def pretty(path)
|
12
|
+
Terraspace::Util.pretty_path(path)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Terraspace::CLI::Clean
|
2
|
+
class Cache < Base
|
3
|
+
def run
|
4
|
+
Terraspace.check_project!
|
5
|
+
paths = [Terraspace.cache_root, Terraspace.tmp_root]
|
6
|
+
are_you_sure?(paths)
|
7
|
+
paths.each do |path|
|
8
|
+
FileUtils.rm_rf(path)
|
9
|
+
puts "Removed #{pretty(path)}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def are_you_sure?(paths)
|
14
|
+
pretty_paths = paths.map { |p| " #{pretty(p)}" }.join("\n")
|
15
|
+
message = <<~EOL.chomp
|
16
|
+
Will remove these folders and all their files:
|
17
|
+
|
18
|
+
#{pretty_paths}
|
19
|
+
|
20
|
+
Are you sure?
|
21
|
+
EOL
|
22
|
+
sure?(message) # from Util::Sure
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,21 +1,19 @@
|
|
1
|
-
class Terraspace::CLI::
|
2
|
-
class
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@options
|
7
|
-
|
1
|
+
class Terraspace::CLI::Clean
|
2
|
+
class Logs < Base
|
3
|
+
def run
|
4
|
+
action = @options[:truncate] ? "truncate" : "remove"
|
5
|
+
are_you_sure?(action)
|
6
|
+
@options[:truncate] ? truncate : remove
|
7
|
+
logger.info "Logs #{action}d" # IE: Logs truncated or Logs removed
|
8
8
|
end
|
9
9
|
|
10
10
|
def truncate
|
11
|
-
are_you_sure?("truncate")
|
12
11
|
log_files.each do |path|
|
13
12
|
File.open(path, "w").close # truncates files
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
16
|
def remove
|
18
|
-
are_you_sure?("remove")
|
19
17
|
puts "Removing all files in #{pretty_log_root}/" unless @options[:mute]
|
20
18
|
FileUtils.rm_rf(log_root)
|
21
19
|
FileUtils.mkdir_p(log_root)
|
@@ -42,3 +40,4 @@ class Terraspace::CLI::Logs
|
|
42
40
|
end
|
43
41
|
end
|
44
42
|
end
|
43
|
+
|
data/lib/terraspace/cli/cloud.rb
CHANGED
@@ -16,6 +16,7 @@ class Terraspace::CLI
|
|
16
16
|
|
17
17
|
desc "destroy STACK", "Destroy workspace by specifying the stack"
|
18
18
|
long_desc Help.text("cloud:destroy")
|
19
|
+
yes_option.call
|
19
20
|
def destroy(mod)
|
20
21
|
Workspace.new(options.merge(mod: mod)).destroy
|
21
22
|
end
|
@@ -24,6 +25,7 @@ class Terraspace::CLI
|
|
24
25
|
long_desc Help.text("cloud:sync")
|
25
26
|
yes_option.call
|
26
27
|
def sync(*stacks)
|
28
|
+
Terraspace::CLI::Build::Placeholder.new(options).build
|
27
29
|
Syncer.new(options.merge(stacks: stacks, override_auto_sync: true)).run
|
28
30
|
end
|
29
31
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
## Example
|
2
|
+
|
3
|
+
$ terraspace all init
|
4
|
+
Building one stack to build all stacks
|
5
|
+
Building .terraspace-cache/us-west-2/dev/stacks/c1
|
6
|
+
Downloading tfstate files for dependencies defined in tfvars...
|
7
|
+
Built in .terraspace-cache/us-west-2/dev/stacks/c1
|
8
|
+
Running:
|
9
|
+
terraspace init c1 # batch 1
|
10
|
+
terraspace init b1 # batch 2
|
11
|
+
terraspace init b2 # batch 2
|
12
|
+
terraspace init a1 # batch 3
|
13
|
+
Batch Run 1:
|
14
|
+
Running: terraspace init c1 Logs: log/init/c1.log
|
15
|
+
terraspace init c1: Terraform has been successfully initialized!
|
16
|
+
Batch Run 2:
|
17
|
+
Running: terraspace init b1 Logs: log/init/b1.log
|
18
|
+
Running: terraspace init b2 Logs: log/init/b2.log
|
19
|
+
terraspace init b1: Terraform has been successfully initialized!
|
20
|
+
terraspace init b2: Terraform has been successfully initialized!
|
21
|
+
Batch Run 3:
|
22
|
+
Running: terraspace init a1 Logs: log/init/a1.log
|
23
|
+
terraspace init a1: Terraform has been successfully initialized!
|
24
|
+
Time took: 6s
|
25
|
+
$
|
26
|
+
|
27
|
+
If Terraform is having trouble initializing, clearing the cache may help:
|
28
|
+
|
29
|
+
$ terraspace clean cache -y
|
30
|
+
Removed .terraspace-cache
|
31
|
+
Removed /tmp/terraspace
|
32
|
+
|
33
|
+
Also consider disabling the [terraform.plugin_cache.enabled](https://terraspace.cloud/docs/config/reference/).
|
@@ -0,0 +1,17 @@
|
|
1
|
+
## Examples
|
2
|
+
|
3
|
+
Remove logs completely:
|
4
|
+
|
5
|
+
$ terraspace clean logs
|
6
|
+
Will remove all the log files in log/ folder
|
7
|
+
Are you sure? (y/N) y
|
8
|
+
Removing all files in log/
|
9
|
+
Logs removed
|
10
|
+
|
11
|
+
Truncate logs. IE: Keeps the files but removes contents and zero bytes the files.
|
12
|
+
|
13
|
+
$ terraspace clean logs --truncate
|
14
|
+
Will truncate all the log files in log/ folder
|
15
|
+
Are you sure? (y/N) y
|
16
|
+
Logs truncated
|
17
|
+
$
|
@@ -0,0 +1,48 @@
|
|
1
|
+
The log commands will filter out the logs for the last ran terraspace command. It does this by filtering for the last found PID in the log files.
|
2
|
+
|
3
|
+
## Quick Start
|
4
|
+
|
5
|
+
Follow all the logs as you're running `terraspace all up`:
|
6
|
+
|
7
|
+
terraspace logs -f
|
8
|
+
|
9
|
+
Note, Terraspace automatically checks every second for new logs and adds them to be followed.
|
10
|
+
|
11
|
+
## View Logs
|
12
|
+
|
13
|
+
View last 10 lines of each log file.
|
14
|
+
|
15
|
+
terraspace logs up network # view up log on a specific stack
|
16
|
+
terraspace logs up # view all up logs
|
17
|
+
terraspace logs down # view all down logs
|
18
|
+
terraspace logs # view all logs: up, down, etc
|
19
|
+
|
20
|
+
By default, the logs command shows the last 10 lines for each log file. You can use the `-n` option to adjust this.
|
21
|
+
|
22
|
+
terraspace logs -n 2 # view last 2 lines of all logs: up, down, etc
|
23
|
+
|
24
|
+
To show all logs, use the `-a` option.
|
25
|
+
|
26
|
+
terraspace logs up -a
|
27
|
+
|
28
|
+
Note, if both an action and stack is specified, then it defaults to showing all logs. If you want not to show all logs, use `--no-all`.
|
29
|
+
|
30
|
+
## Tail Logs
|
31
|
+
|
32
|
+
To tail logs, use the `-f` option.
|
33
|
+
|
34
|
+
terraspace logs up network -f # view up log on a specific stack
|
35
|
+
terraspace logs up -f # view all up logs
|
36
|
+
terraspace logs down -f # view all down logs
|
37
|
+
terraspace logs -f # view all logs: up, down, etc
|
38
|
+
|
39
|
+
## Timestamps
|
40
|
+
|
41
|
+
The timestamps are shown by default when you are looking for multiple files. When you specify both the action and stack for a single log file, the timestamps are not shown.
|
42
|
+
|
43
|
+
terraspace logs up # timestamps will be shown in this case
|
44
|
+
terraspace logs up network # timestamps not be shown in this case
|
45
|
+
|
46
|
+
To show timestamps:
|
47
|
+
|
48
|
+
terraspace logs up network --timestamps
|
data/lib/terraspace/cli/info.rb
CHANGED
@@ -3,6 +3,14 @@ class Terraspace::CLI
|
|
3
3
|
extend Memoist
|
4
4
|
|
5
5
|
def run
|
6
|
+
if @options[:path]
|
7
|
+
show_path
|
8
|
+
else
|
9
|
+
show_all
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def show_all
|
6
14
|
presenter = CliFormat::Presenter.new(@options)
|
7
15
|
presenter.header = %w[Name Value]
|
8
16
|
info.each do |k,v|
|
@@ -11,6 +19,10 @@ class Terraspace::CLI
|
|
11
19
|
presenter.show
|
12
20
|
end
|
13
21
|
|
22
|
+
def show_path
|
23
|
+
puts info[:cache_dir]
|
24
|
+
end
|
25
|
+
|
14
26
|
def info
|
15
27
|
@mod.to_info
|
16
28
|
end
|
data/lib/terraspace/cli/init.rb
CHANGED
@@ -67,7 +67,7 @@ class Terraspace::CLI
|
|
67
67
|
mode = ENV['TS_INIT_MODE'] || Terraspace.config.init.mode
|
68
68
|
case mode.to_sym
|
69
69
|
when :auto
|
70
|
-
!
|
70
|
+
!already_init?
|
71
71
|
when :always
|
72
72
|
true
|
73
73
|
when :never
|
@@ -80,16 +80,12 @@ class Terraspace::CLI
|
|
80
80
|
# Traverse symlink dirs also: linux_amd64 is a symlink
|
81
81
|
# plugins/registry.terraform.io/hashicorp/google/3.39.0/linux_amd64/terraform-provider-google_v3.39.0_x5
|
82
82
|
#
|
83
|
-
|
84
|
-
# So init happens again during the second pass.
|
85
|
-
#
|
86
|
-
def already_initialized?
|
83
|
+
def already_init?
|
87
84
|
terraform = "#{@mod.cache_dir}/.terraform"
|
88
85
|
provider = Dir.glob("#{terraform}/**{,/*/**}/*").find do |path|
|
89
86
|
path.include?("terraform-provider-")
|
90
87
|
end
|
91
|
-
|
92
|
-
!!(provider && modules)
|
88
|
+
!!provider
|
93
89
|
end
|
94
90
|
end
|
95
91
|
end
|
data/lib/terraspace/cli/list.rb
CHANGED
@@ -6,7 +6,8 @@ class Terraspace::CLI
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def run
|
9
|
-
Dir.glob("{app,vendor}/{modules,stacks}/*").
|
9
|
+
dirs = Dir.glob("{app,vendor}/{modules,stacks}/*").select { |p| File.directory?(p) }
|
10
|
+
dirs.sort.each do |path|
|
10
11
|
if @type_dir
|
11
12
|
puts path if path.include?("/#{@type_dir}/")
|
12
13
|
else
|
data/lib/terraspace/cli/logs.rb
CHANGED
@@ -1,17 +1,112 @@
|
|
1
|
+
require "eventmachine"
|
2
|
+
require "eventmachine-tail"
|
3
|
+
|
1
4
|
class Terraspace::CLI
|
2
|
-
class Logs <
|
3
|
-
|
5
|
+
class Logs < Base
|
6
|
+
include Concern
|
7
|
+
|
8
|
+
def initialize(options={})
|
9
|
+
super
|
10
|
+
@action, @stack = options[:action], options[:stack]
|
11
|
+
@action ||= '**'
|
12
|
+
@stack ||= '*'
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
check_logs!
|
17
|
+
if @options[:follow]
|
18
|
+
follow_logs
|
19
|
+
else
|
20
|
+
all_log_paths.each { |path| show_log(path) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def follow_logs
|
25
|
+
glob_path = "#{Terraspace.log_root}/#{@action}/#{@stack}.log"
|
26
|
+
Dir.glob(glob_path).each do |path|
|
27
|
+
puts "Following #{pretty(path)}".color(:purple)
|
28
|
+
end
|
29
|
+
EventMachine.run do
|
30
|
+
interval = Integer(ENV['TS_LOG_GLOB_INTERNAL'] || 1)
|
31
|
+
EventMachine::FileGlobWatchTail.new(glob_path, nil, interval) do |filetail, line|
|
32
|
+
puts line # always show timestamp in follow mode
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def show_log(path)
|
38
|
+
report_log(path)
|
39
|
+
lines = readlines(path)
|
40
|
+
lines = apply_limit(lines)
|
41
|
+
lines.each do |line|
|
42
|
+
puts format(line)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def report_log(path)
|
47
|
+
pretty_path = pretty(path)
|
48
|
+
if File.exist?(path)
|
49
|
+
puts "Showing: #{pretty_path}".color(:purple)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def format(line)
|
54
|
+
if timestamps
|
55
|
+
line
|
56
|
+
else
|
57
|
+
line.sub(/.*\]: /,'')
|
58
|
+
end
|
59
|
+
end
|
4
60
|
|
5
|
-
|
6
|
-
|
7
|
-
def truncate
|
8
|
-
Tasks.new(options).truncate
|
61
|
+
def all_log_paths
|
62
|
+
Dir.glob("#{Terraspace.log_root}/#{@action}/#{@stack}.log")
|
9
63
|
end
|
10
64
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
65
|
+
def check_logs!
|
66
|
+
return unless all_log_paths.empty?
|
67
|
+
puts "WARN: No logs found".color(:yellow)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Only need to check if both action and stack are provided. Otherwise the Dir.globs are used to discover the files
|
71
|
+
def check_log!
|
72
|
+
return unless single_log?
|
73
|
+
path = "#{Terraspace.log_root}/#{@action}/#{@stack}.log"
|
74
|
+
return if File.exist?(path)
|
75
|
+
puts "ERROR: Log file was not found: #{pretty(path)}".color(:red)
|
76
|
+
exit 1
|
77
|
+
end
|
78
|
+
|
79
|
+
def single_log?
|
80
|
+
@action != '**' && @stack != '*'
|
81
|
+
end
|
82
|
+
|
83
|
+
def apply_limit(lines)
|
84
|
+
return lines if all
|
85
|
+
left = limit * -1
|
86
|
+
lines[left..-1] || []
|
87
|
+
end
|
88
|
+
|
89
|
+
def all
|
90
|
+
if single_log?
|
91
|
+
@options[:all].nil? ? true : @options[:all]
|
92
|
+
else # multiple
|
93
|
+
@options[:all].nil? ? false : @options[:all]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def limit
|
98
|
+
@options[:limit].nil? ? 10 : @options[:limit]
|
99
|
+
end
|
100
|
+
|
101
|
+
def timestamps
|
102
|
+
if single_log?
|
103
|
+
@options[:timestamps].nil? ? false : @options[:timestamps]
|
104
|
+
else
|
105
|
+
@options[:timestamps].nil? ? true : @options[:timestamps]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
def pretty(path)
|
109
|
+
Terraspace::Util.pretty_path(path)
|
15
110
|
end
|
16
111
|
end
|
17
112
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Terraspace::CLI::
|
1
|
+
class Terraspace::CLI::Logs
|
2
2
|
module Concern
|
3
3
|
# Filters for lines that belong to the last ran process pid
|
4
4
|
def readlines(path)
|
@@ -17,6 +17,7 @@ class Terraspace::CLI::Log
|
|
17
17
|
|
18
18
|
# [2020-09-06T21:58:25 #11313 terraspace up b1]:
|
19
19
|
def pid(line)
|
20
|
+
return @options[:pid] if @options && @options[:pid] # Terraspace::All::Summary: doesnt have @options set
|
20
21
|
md = line.match(/:\d{2} #(\d+) /)
|
21
22
|
md[1] if md
|
22
23
|
end
|
@@ -6,10 +6,17 @@ class Terraspace::CLI::New
|
|
6
6
|
def build_gemfile(*list)
|
7
7
|
lines = []
|
8
8
|
list.each do |name|
|
9
|
-
|
10
|
-
lines << line
|
9
|
+
lines << gem_line(name)
|
11
10
|
end
|
12
11
|
lines.join("\n")
|
13
12
|
end
|
13
|
+
|
14
|
+
def gem_line(name)
|
15
|
+
if name == "terraspace"
|
16
|
+
%Q|gem "#{name}", '~> #{Terraspace::VERSION}'|
|
17
|
+
else
|
18
|
+
%Q|gem "#{name}"|
|
19
|
+
end
|
20
|
+
end
|
14
21
|
end
|
15
22
|
end
|
@@ -4,7 +4,7 @@ module Terraspace::Dependency::Helper
|
|
4
4
|
if @mod.resolved # dependencies have been resolved
|
5
5
|
Terraspace::Terraform::RemoteState::Fetcher.new(@mod, @identifier, @options).output # Returns OutputProxy which defaults to json
|
6
6
|
else
|
7
|
-
Terraspace::Terraform::RemoteState::Marker::Output.new(@mod, @identifier, @options).build # Returns OutputProxy
|
7
|
+
Terraspace::Terraform::RemoteState::Marker::Output.new(@mod, @identifier, @options).build # Returns OutputProxy => Unresolved
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|