ops_team 1.21.1 → 2.0.0.rc3
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/bin/ops +4 -40
- data/build/darwin_amd64/ops +0 -0
- data/build/darwin_arm64/ops +0 -0
- data/build/linux_amd64/ops +0 -0
- metadata +12 -224
- data/Gemfile +0 -30
- data/bin/benchmark +0 -185
- data/bin/print_config +0 -4
- data/bin/print_secrets +0 -4
- data/bin/tag +0 -16
- data/etc/ops.template.yml +0 -13
- data/etc/ruby.template.yml +0 -37
- data/etc/terraform.template.yml +0 -36
- data/lib/action.rb +0 -103
- data/lib/action_list.rb +0 -55
- data/lib/action_suggester.rb +0 -17
- data/lib/app_config.rb +0 -69
- data/lib/builtin.rb +0 -51
- data/lib/builtins/background.rb +0 -46
- data/lib/builtins/background_log.rb +0 -34
- data/lib/builtins/common/up_down.rb +0 -67
- data/lib/builtins/countdown.rb +0 -73
- data/lib/builtins/down.rb +0 -9
- data/lib/builtins/env.rb +0 -21
- data/lib/builtins/envdiff.rb +0 -127
- data/lib/builtins/exec.rb +0 -24
- data/lib/builtins/help.rb +0 -66
- data/lib/builtins/helpers/dependency_handler.rb +0 -27
- data/lib/builtins/helpers/enumerator.rb +0 -34
- data/lib/builtins/init.rb +0 -64
- data/lib/builtins/up.rb +0 -9
- data/lib/builtins/version.rb +0 -17
- data/lib/dependencies/apk.rb +0 -24
- data/lib/dependencies/apt.rb +0 -42
- data/lib/dependencies/brew.rb +0 -22
- data/lib/dependencies/cask.rb +0 -13
- data/lib/dependencies/custom.rb +0 -45
- data/lib/dependencies/dir.rb +0 -22
- data/lib/dependencies/docker.rb +0 -17
- data/lib/dependencies/gem.rb +0 -36
- data/lib/dependencies/helpers/apt_cache_policy.rb +0 -43
- data/lib/dependencies/pip.rb +0 -32
- data/lib/dependencies/snap.rb +0 -32
- data/lib/dependencies/sshkey.rb +0 -121
- data/lib/dependencies/versioned_dependency.rb +0 -25
- data/lib/dependency.rb +0 -69
- data/lib/environment.rb +0 -47
- data/lib/executor.rb +0 -20
- data/lib/forward.rb +0 -15
- data/lib/forwards.rb +0 -16
- data/lib/hook_handler.rb +0 -41
- data/lib/ops.rb +0 -129
- data/lib/options.rb +0 -22
- data/lib/output.rb +0 -71
- data/lib/profiler.rb +0 -47
- data/lib/runner.rb +0 -110
- data/lib/secrets.rb +0 -55
- data/lib/version.rb +0 -38
- data/loader.rb +0 -10
- data/ops_team.gemspec +0 -36
data/lib/action.rb
DELETED
@@ -1,103 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# represents one action to be performed in the shell
|
4
|
-
# can assemble a command line from a command and args
|
5
|
-
class Action
|
6
|
-
attr_reader :name
|
7
|
-
|
8
|
-
def initialize(name, config, args)
|
9
|
-
@name = name
|
10
|
-
@config = config || {}
|
11
|
-
@args = args
|
12
|
-
end
|
13
|
-
|
14
|
-
def run
|
15
|
-
Output.error(Profiler.summary) if Profiler.summary
|
16
|
-
|
17
|
-
if perform_shell_expansion?
|
18
|
-
Kernel.exec(to_s)
|
19
|
-
else
|
20
|
-
Kernel.exec(*to_a)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def to_s
|
25
|
-
"#{command} #{@args.join(' ')}".strip
|
26
|
-
end
|
27
|
-
|
28
|
-
def alias
|
29
|
-
@config["alias"] || @config["aliases"]&.first
|
30
|
-
end
|
31
|
-
|
32
|
-
def aliases
|
33
|
-
return [@config["alias"]].compact unless @config["aliases"]
|
34
|
-
|
35
|
-
([@config["alias"]] + @config["aliases"]).compact
|
36
|
-
end
|
37
|
-
|
38
|
-
def command
|
39
|
-
return @config if @config.is_a?(String)
|
40
|
-
|
41
|
-
@config["command"]
|
42
|
-
end
|
43
|
-
|
44
|
-
def description
|
45
|
-
@config["description"]
|
46
|
-
end
|
47
|
-
|
48
|
-
def skip_hooks?(name)
|
49
|
-
@config["skip_#{name}_hooks"]
|
50
|
-
end
|
51
|
-
|
52
|
-
def config_valid?
|
53
|
-
config_errors.empty?
|
54
|
-
end
|
55
|
-
|
56
|
-
def config_errors
|
57
|
-
@config_errors ||= begin
|
58
|
-
errors = []
|
59
|
-
|
60
|
-
errors << "No 'command' specified in 'action'." unless command
|
61
|
-
|
62
|
-
errors
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def load_secrets?
|
67
|
-
@config["load_secrets"].nil? ? false : @config["load_secrets"]
|
68
|
-
end
|
69
|
-
|
70
|
-
def execute_in_env?(env)
|
71
|
-
!skip_in_envs.include?(env)
|
72
|
-
end
|
73
|
-
|
74
|
-
def allowed_in_env?(env)
|
75
|
-
return false if not_in_envs.include?(env)
|
76
|
-
|
77
|
-
return false if in_envs.any? && !in_envs.include?(env)
|
78
|
-
|
79
|
-
true
|
80
|
-
end
|
81
|
-
|
82
|
-
private
|
83
|
-
|
84
|
-
def to_a
|
85
|
-
command.split(" ").reject(&:nil?) | @args
|
86
|
-
end
|
87
|
-
|
88
|
-
def not_in_envs
|
89
|
-
@config["not_in_envs"] || []
|
90
|
-
end
|
91
|
-
|
92
|
-
def in_envs
|
93
|
-
@config["in_envs"] || []
|
94
|
-
end
|
95
|
-
|
96
|
-
def skip_in_envs
|
97
|
-
@config["skip_in_envs"] || []
|
98
|
-
end
|
99
|
-
|
100
|
-
def perform_shell_expansion?
|
101
|
-
@config["shell_expansion"].nil? ? true : @config["shell_expansion"]
|
102
|
-
end
|
103
|
-
end
|
data/lib/action_list.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class ActionList
|
4
|
-
class UnknownActionError < StandardError; end
|
5
|
-
|
6
|
-
def initialize(actions_list, args)
|
7
|
-
@actions_list = actions_list
|
8
|
-
@args = args
|
9
|
-
|
10
|
-
process_action_list
|
11
|
-
end
|
12
|
-
|
13
|
-
def get(name)
|
14
|
-
@actions[name]
|
15
|
-
end
|
16
|
-
|
17
|
-
def get_by_alias(name)
|
18
|
-
@aliases[name]
|
19
|
-
end
|
20
|
-
|
21
|
-
def names
|
22
|
-
@actions.keys
|
23
|
-
end
|
24
|
-
|
25
|
-
def aliases
|
26
|
-
@aliases.keys
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def actions_list
|
32
|
-
@actions_list ||= []
|
33
|
-
end
|
34
|
-
|
35
|
-
def process_action_list
|
36
|
-
@actions = {}
|
37
|
-
@aliases = {}
|
38
|
-
|
39
|
-
actions_list.each do |name, config|
|
40
|
-
action = Action.new(name, config, @args)
|
41
|
-
|
42
|
-
@actions[name] = action
|
43
|
-
action.aliases.each do |aliaz|
|
44
|
-
check_duplicate_alias(name, aliaz)
|
45
|
-
@aliases[aliaz] = action
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def check_duplicate_alias(name, aliaz)
|
51
|
-
return if @aliases[aliaz].nil?
|
52
|
-
|
53
|
-
Output.warn("Duplicate alias '#{aliaz}' detected in action '#{name}'.")
|
54
|
-
end
|
55
|
-
end
|
data/lib/action_suggester.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class ActionSuggester
|
4
|
-
def initialize(dictionary)
|
5
|
-
@dictionary = dictionary
|
6
|
-
end
|
7
|
-
|
8
|
-
def check(word)
|
9
|
-
spellchecker.correct(word)
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def spellchecker
|
15
|
-
@spellchecker ||= DidYouMean::SpellChecker.new(dictionary: @dictionary)
|
16
|
-
end
|
17
|
-
end
|
data/lib/app_config.rb
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
class AppConfig
|
6
|
-
class ParsingError < StandardError; end
|
7
|
-
|
8
|
-
class << self
|
9
|
-
def load
|
10
|
-
new(app_config_path).load
|
11
|
-
end
|
12
|
-
|
13
|
-
def default_filename
|
14
|
-
config_path_for(Environment.environment)
|
15
|
-
end
|
16
|
-
|
17
|
-
def config_path_for(env)
|
18
|
-
"config/#{env}/config.json"
|
19
|
-
end
|
20
|
-
|
21
|
-
def app_config_path
|
22
|
-
expand_path(Options.get("config.path") || default_filename)
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def expand_path(path)
|
28
|
-
`echo #{path}`.chomp
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def load
|
33
|
-
config['environment']&.each do |key, value|
|
34
|
-
if Options.get("config.preserve_existing_env_vars") && ENV[key]
|
35
|
-
Output.debug("Environment variable '$#{key}' already set; skipping...")
|
36
|
-
next
|
37
|
-
end
|
38
|
-
|
39
|
-
ENV[key] = value.is_a?(Hash) || value.is_a?(Array) ? value.to_json : value.to_s
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def initialize(filename = "")
|
46
|
-
@filename = filename
|
47
|
-
end
|
48
|
-
|
49
|
-
def config
|
50
|
-
@config ||= if file_contents == ""
|
51
|
-
Output.warn("Config file '#{@filename}' exists but is empty.")
|
52
|
-
{}
|
53
|
-
elsif file_contents
|
54
|
-
YAML.safe_load(file_contents)
|
55
|
-
else
|
56
|
-
{}
|
57
|
-
end
|
58
|
-
rescue YAML::SyntaxError => e
|
59
|
-
raise ParsingError, "#{@filename}: #{e}"
|
60
|
-
end
|
61
|
-
|
62
|
-
def file_contents
|
63
|
-
@file_contents ||= begin
|
64
|
-
File.open(@filename).read
|
65
|
-
rescue Errno::ENOENT
|
66
|
-
nil
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
data/lib/builtin.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Builtin
|
4
|
-
class ArgumentError < StandardError; end
|
5
|
-
|
6
|
-
attr_reader :args, :config
|
7
|
-
|
8
|
-
class << self
|
9
|
-
BUILTIN_DIR = "builtins"
|
10
|
-
|
11
|
-
def description
|
12
|
-
"no description"
|
13
|
-
end
|
14
|
-
|
15
|
-
def class_for(name:)
|
16
|
-
file = file_for(name: name)
|
17
|
-
unless File.exist?(file)
|
18
|
-
require 'require_all'
|
19
|
-
require_rel "builtins"
|
20
|
-
end
|
21
|
-
|
22
|
-
get_const(name: builtin_class_name_for(name: name))
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def get_const(name:)
|
28
|
-
Builtins.const_get(name, false)
|
29
|
-
rescue NameError
|
30
|
-
# no such constant
|
31
|
-
nil
|
32
|
-
end
|
33
|
-
|
34
|
-
def file_for(name:)
|
35
|
-
File.join(File.dirname(__FILE__), BUILTIN_DIR, "#{name}.rb")
|
36
|
-
end
|
37
|
-
|
38
|
-
def builtin_class_name_for(name:)
|
39
|
-
name.capitalize.to_sym
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def initialize(args, config)
|
44
|
-
@args = args
|
45
|
-
@config = config
|
46
|
-
end
|
47
|
-
|
48
|
-
def run
|
49
|
-
raise NotImplementedError
|
50
|
-
end
|
51
|
-
end
|
data/lib/builtins/background.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Builtins
|
4
|
-
class Background < ::Builtin
|
5
|
-
DEFAULT_LOG_FILE_PREFIX = "/tmp/ops_bglog_"
|
6
|
-
|
7
|
-
class << self
|
8
|
-
def description
|
9
|
-
"runs the given command in a background session"
|
10
|
-
end
|
11
|
-
|
12
|
-
def log_filename
|
13
|
-
Options.get("background.log_filename") || "#{DEFAULT_LOG_FILE_PREFIX}#{Ops.project_name}"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def run
|
18
|
-
subprocess = fork do
|
19
|
-
set_bglog_file_permissions
|
20
|
-
run_ops(args)
|
21
|
-
end
|
22
|
-
|
23
|
-
Process.detach(subprocess)
|
24
|
-
|
25
|
-
true
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def set_bglog_file_permissions
|
31
|
-
File.new(Background.log_filename, "w").chmod(0o600)
|
32
|
-
end
|
33
|
-
|
34
|
-
def run_ops(args)
|
35
|
-
Output.notice("Running '#{args.join(' ')}' with stderr and stdout redirected to '#{Background.log_filename}'")
|
36
|
-
$stdout.sync = $stderr.sync = true
|
37
|
-
$stdout.reopen(Background.log_filename, "w")
|
38
|
-
$stderr.reopen($stdout)
|
39
|
-
|
40
|
-
Ops.new(args).run
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# set an alias
|
45
|
-
Bg = Background
|
46
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Builtins
|
4
|
-
class BackgroundLog < Builtin
|
5
|
-
class << self
|
6
|
-
def description
|
7
|
-
"displays the log from the current or most recent background task from this project"
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def run
|
12
|
-
unless File.exist?(Background.log_filename)
|
13
|
-
Output.warn("No background log found at '#{Background.log_filename}'.")
|
14
|
-
return 0
|
15
|
-
end
|
16
|
-
|
17
|
-
Output.notice("Displaying background log '#{Background.log_filename}'...")
|
18
|
-
display_file
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def display_file
|
24
|
-
if args.any?
|
25
|
-
exec("tail #{args.join(' ')} '#{Background.log_filename}'")
|
26
|
-
else
|
27
|
-
exec("cat '#{Background.log_filename}'")
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# set an alias
|
33
|
-
Bglog = BackgroundLog
|
34
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Builtins
|
4
|
-
module Common
|
5
|
-
class UpDown < Builtin
|
6
|
-
class << self
|
7
|
-
def description
|
8
|
-
"attempts to meet dependencies listed in ops.yml"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def run
|
13
|
-
meet_dependencies
|
14
|
-
|
15
|
-
return true unless fail_on_error?
|
16
|
-
|
17
|
-
deps_to_meet.all?(&:success?)
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def meet_dependencies
|
23
|
-
deps_to_meet.each do |dependency|
|
24
|
-
Output.status("[#{dependency.type}] #{dependency.name}")
|
25
|
-
|
26
|
-
meet_dependency(dependency)
|
27
|
-
|
28
|
-
break if dependency.failure? && exit_on_error?
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def meet_dependency(dependency)
|
33
|
-
handle_dependency(dependency) if !dependency.met? || dependency.always_act?
|
34
|
-
|
35
|
-
if dependency.success?
|
36
|
-
Output.okay
|
37
|
-
else
|
38
|
-
Output.failed
|
39
|
-
Output.error("Error meeting #{dependency.type} dependency '#{dependency.name}':")
|
40
|
-
Output.out(dependency.output)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def deps_to_meet
|
45
|
-
@deps_to_meet ||= dependency_handler.dependencies.select(&:should_meet?)
|
46
|
-
end
|
47
|
-
|
48
|
-
def dependency_handler
|
49
|
-
Helpers::DependencyHandler.new(dependencies)
|
50
|
-
end
|
51
|
-
|
52
|
-
def dependencies
|
53
|
-
return @config["dependencies"] if @args.empty?
|
54
|
-
|
55
|
-
@config["dependencies"].select { |dep, _names| @args.include?(dep) }
|
56
|
-
end
|
57
|
-
|
58
|
-
def fail_on_error?
|
59
|
-
Options.get("up.fail_on_error") || false
|
60
|
-
end
|
61
|
-
|
62
|
-
def exit_on_error?
|
63
|
-
Options.get("up.exit_on_error") || false
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
data/lib/builtins/countdown.rb
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'concurrent'
|
4
|
-
|
5
|
-
module Builtins
|
6
|
-
class Countdown < Builtin
|
7
|
-
USAGE_STRING = "Usage: ops countdown <seconds>"
|
8
|
-
|
9
|
-
class << self
|
10
|
-
def description
|
11
|
-
"Like `sleep`, but displays time remaining in terminal."
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def run
|
16
|
-
check_args
|
17
|
-
|
18
|
-
timer_task.execute
|
19
|
-
|
20
|
-
while timer_task.running?
|
21
|
-
sleep(1)
|
22
|
-
timer_task.shutdown if task_complete?
|
23
|
-
end
|
24
|
-
Output.out("\rCountdown complete after #{sleep_seconds}s.")
|
25
|
-
|
26
|
-
true
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def check_args
|
32
|
-
check_arg_count
|
33
|
-
check_arg_is_positive_int
|
34
|
-
end
|
35
|
-
|
36
|
-
def check_arg_count
|
37
|
-
raise Builtin::ArgumentError, USAGE_STRING unless args.length == 1
|
38
|
-
end
|
39
|
-
|
40
|
-
def check_arg_is_positive_int
|
41
|
-
raise Builtin::ArgumentError, USAGE_STRING unless sleep_seconds.positive?
|
42
|
-
# raised when the arg is not an int
|
43
|
-
rescue ::ArgumentError
|
44
|
-
raise Builtin::ArgumentError, USAGE_STRING
|
45
|
-
end
|
46
|
-
|
47
|
-
def timer_task
|
48
|
-
@timer_task ||= Concurrent::TimerTask.new(run_now: true, execution_interval: 1) do
|
49
|
-
Output.print("\r \r#{seconds_left}")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def sleep_seconds
|
54
|
-
Integer(args.first)
|
55
|
-
end
|
56
|
-
|
57
|
-
def task_start_time
|
58
|
-
@task_start_time ||= Time.now
|
59
|
-
end
|
60
|
-
|
61
|
-
def task_end_time
|
62
|
-
@task_end_time ||= task_start_time + sleep_seconds
|
63
|
-
end
|
64
|
-
|
65
|
-
def task_complete?
|
66
|
-
Time.now > task_end_time
|
67
|
-
end
|
68
|
-
|
69
|
-
def seconds_left
|
70
|
-
Integer(task_end_time - Time.now + 1)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
data/lib/builtins/down.rb
DELETED
data/lib/builtins/env.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Builtins
|
4
|
-
class Env < Builtin
|
5
|
-
class << self
|
6
|
-
def description
|
7
|
-
"prints the current environment, e.g. 'dev', 'production', 'staging', etc."
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def run
|
12
|
-
Output.print(environment)
|
13
|
-
|
14
|
-
true
|
15
|
-
end
|
16
|
-
|
17
|
-
def environment
|
18
|
-
ENV['environment']
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/lib/builtins/envdiff.rb
DELETED
@@ -1,127 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Builtins
|
4
|
-
class Envdiff < Builtin
|
5
|
-
class << self
|
6
|
-
def description
|
7
|
-
"compares keys present in config and secrets between different environments"
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def run
|
12
|
-
check_args
|
13
|
-
|
14
|
-
if source_only_keys.empty? && dest_only_keys.empty?
|
15
|
-
Output.out("Environments '#{source_env}' and '#{dest_env}' define the same #{source_keys.length} key(s).")
|
16
|
-
return
|
17
|
-
end
|
18
|
-
|
19
|
-
output_key_summary(source_only_keys, source_env, dest_env) if source_only_keys.any?
|
20
|
-
output_key_summary(dest_only_keys, dest_env, source_env) if dest_only_keys.any?
|
21
|
-
|
22
|
-
true
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def output_key_summary(keys, in_env, not_in_env)
|
28
|
-
Output.warn("Environment '#{in_env}' defines keys that '#{not_in_env}' does not:\n")
|
29
|
-
keys.each do |key|
|
30
|
-
Output.warn(" - #{key}")
|
31
|
-
end
|
32
|
-
Output.out("")
|
33
|
-
end
|
34
|
-
|
35
|
-
def source_only_keys
|
36
|
-
@source_only_keys ||= source_keys - dest_keys
|
37
|
-
end
|
38
|
-
|
39
|
-
def dest_only_keys
|
40
|
-
@dest_only_keys ||= dest_keys - source_keys
|
41
|
-
end
|
42
|
-
|
43
|
-
def source_keys
|
44
|
-
@source_keys ||= keys_for(source_env)
|
45
|
-
end
|
46
|
-
|
47
|
-
def dest_keys
|
48
|
-
@dest_keys ||= keys_for(dest_env)
|
49
|
-
end
|
50
|
-
|
51
|
-
def keys_for(env)
|
52
|
-
tagged_config_keys_for(env) + tagged_secrets_keys_for(env)
|
53
|
-
end
|
54
|
-
|
55
|
-
def tagged_config_keys_for(env)
|
56
|
-
config_keys_for(env).map do |key|
|
57
|
-
"[CONFIG] #{key}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def tagged_secrets_keys_for(env)
|
62
|
-
secrets_keys_for(env).map do |key|
|
63
|
-
"[SECRET] #{key}"
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def config_keys_for(env)
|
68
|
-
(config_for(env)["environment"]&.keys || []) - ignored_keys
|
69
|
-
end
|
70
|
-
|
71
|
-
def secrets_keys_for(env)
|
72
|
-
(secrets_for(env)["environment"]&.keys || []) - ignored_keys
|
73
|
-
end
|
74
|
-
|
75
|
-
def config_for(env)
|
76
|
-
YAML.load_file(config_path_for(env))
|
77
|
-
end
|
78
|
-
|
79
|
-
def secrets_for(env)
|
80
|
-
YAML.load_file(secrets_path_for(env))
|
81
|
-
end
|
82
|
-
|
83
|
-
def check_args
|
84
|
-
raise Builtin::ArgumentError, "Usage: ops envdiff <env_one> <env_two>" unless args.length == 2
|
85
|
-
|
86
|
-
check_environment(source_env)
|
87
|
-
check_environment(dest_env)
|
88
|
-
end
|
89
|
-
|
90
|
-
def source_env
|
91
|
-
args[0]
|
92
|
-
end
|
93
|
-
|
94
|
-
def dest_env
|
95
|
-
args[1]
|
96
|
-
end
|
97
|
-
|
98
|
-
def check_environment(name)
|
99
|
-
raise_missing_file_error(config_path_for(name)) unless config_file_exists?(name)
|
100
|
-
raise_missing_file_error(secrets_path_for(name)) unless secrets_file_exists?(name)
|
101
|
-
end
|
102
|
-
|
103
|
-
def raise_missing_file_error(path)
|
104
|
-
raise Builtin::ArgumentError, "File '#{path}' does not exist."
|
105
|
-
end
|
106
|
-
|
107
|
-
def config_file_exists?(env)
|
108
|
-
File.exist?(config_path_for(env))
|
109
|
-
end
|
110
|
-
|
111
|
-
def secrets_file_exists?(env)
|
112
|
-
File.exist?(secrets_path_for(env))
|
113
|
-
end
|
114
|
-
|
115
|
-
def config_path_for(env)
|
116
|
-
AppConfig.config_path_for(env)
|
117
|
-
end
|
118
|
-
|
119
|
-
def secrets_path_for(env)
|
120
|
-
Secrets.config_path_for(env)
|
121
|
-
end
|
122
|
-
|
123
|
-
def ignored_keys
|
124
|
-
Options.get("envdiff.ignored_keys") || []
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
data/lib/builtins/exec.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Builtins
|
4
|
-
class Exec < Builtin
|
5
|
-
class << self
|
6
|
-
def description
|
7
|
-
"executes the given command in the `ops` environment, i.e. with environment variables set"
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def run
|
12
|
-
Secrets.load if Options.get("exec.load_secrets")
|
13
|
-
|
14
|
-
if args.any?
|
15
|
-
Output.error(Profiler.summary) if Profiler.summary
|
16
|
-
Kernel.exec(args.join(" "))
|
17
|
-
else
|
18
|
-
Output.error("Usage: ops exec '<command>'")
|
19
|
-
|
20
|
-
false
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|