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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/bin/ops +4 -40
  3. data/build/darwin_amd64/ops +0 -0
  4. data/build/darwin_arm64/ops +0 -0
  5. data/build/linux_amd64/ops +0 -0
  6. metadata +12 -224
  7. data/Gemfile +0 -30
  8. data/bin/benchmark +0 -185
  9. data/bin/print_config +0 -4
  10. data/bin/print_secrets +0 -4
  11. data/bin/tag +0 -16
  12. data/etc/ops.template.yml +0 -13
  13. data/etc/ruby.template.yml +0 -37
  14. data/etc/terraform.template.yml +0 -36
  15. data/lib/action.rb +0 -103
  16. data/lib/action_list.rb +0 -55
  17. data/lib/action_suggester.rb +0 -17
  18. data/lib/app_config.rb +0 -69
  19. data/lib/builtin.rb +0 -51
  20. data/lib/builtins/background.rb +0 -46
  21. data/lib/builtins/background_log.rb +0 -34
  22. data/lib/builtins/common/up_down.rb +0 -67
  23. data/lib/builtins/countdown.rb +0 -73
  24. data/lib/builtins/down.rb +0 -9
  25. data/lib/builtins/env.rb +0 -21
  26. data/lib/builtins/envdiff.rb +0 -127
  27. data/lib/builtins/exec.rb +0 -24
  28. data/lib/builtins/help.rb +0 -66
  29. data/lib/builtins/helpers/dependency_handler.rb +0 -27
  30. data/lib/builtins/helpers/enumerator.rb +0 -34
  31. data/lib/builtins/init.rb +0 -64
  32. data/lib/builtins/up.rb +0 -9
  33. data/lib/builtins/version.rb +0 -17
  34. data/lib/dependencies/apk.rb +0 -24
  35. data/lib/dependencies/apt.rb +0 -42
  36. data/lib/dependencies/brew.rb +0 -22
  37. data/lib/dependencies/cask.rb +0 -13
  38. data/lib/dependencies/custom.rb +0 -45
  39. data/lib/dependencies/dir.rb +0 -22
  40. data/lib/dependencies/docker.rb +0 -17
  41. data/lib/dependencies/gem.rb +0 -36
  42. data/lib/dependencies/helpers/apt_cache_policy.rb +0 -43
  43. data/lib/dependencies/pip.rb +0 -32
  44. data/lib/dependencies/snap.rb +0 -32
  45. data/lib/dependencies/sshkey.rb +0 -121
  46. data/lib/dependencies/versioned_dependency.rb +0 -25
  47. data/lib/dependency.rb +0 -69
  48. data/lib/environment.rb +0 -47
  49. data/lib/executor.rb +0 -20
  50. data/lib/forward.rb +0 -15
  51. data/lib/forwards.rb +0 -16
  52. data/lib/hook_handler.rb +0 -41
  53. data/lib/ops.rb +0 -129
  54. data/lib/options.rb +0 -22
  55. data/lib/output.rb +0 -71
  56. data/lib/profiler.rb +0 -47
  57. data/lib/runner.rb +0 -110
  58. data/lib/secrets.rb +0 -55
  59. data/lib/version.rb +0 -38
  60. data/loader.rb +0 -10
  61. data/ops_team.gemspec +0 -36
data/lib/builtins/help.rb DELETED
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'colorize'
4
-
5
- module Builtins
6
- class Help < Builtin
7
- NAME_WIDTH = 40
8
-
9
- class << self
10
- def description
11
- "displays available builtins, actions, and forwards"
12
- end
13
- end
14
-
15
- def run
16
- list("Builtins", builtins) if builtins.any?
17
- list("Forwards", forwards) if forwards.any?
18
- list("Actions", actions) if actions.any?
19
-
20
- true
21
- end
22
-
23
- private
24
-
25
- def list(name, items)
26
- Output.out("#{name}:")
27
- Output.out(" #{items.join("\n ")}")
28
- Output.out("")
29
- end
30
-
31
- def forwards
32
- Forwards.new(@config).forwards.map do |name, dir|
33
- format("%<name>-#{NAME_WIDTH}s %<desc>s", name: name.yellow, desc: dir.to_s)
34
- end
35
- end
36
-
37
- def builtins
38
- builtin_enumerator.names_by_constant.map do |klass, names|
39
- names_string = names.map(&:downcase).map(&:to_s).uniq.join(", ").yellow
40
-
41
- format("%<names>-#{NAME_WIDTH}s %<desc>s", names: names_string, desc: klass.description)
42
- end
43
- end
44
-
45
- def actions
46
- return [] unless @config["actions"]
47
-
48
- @config["actions"].map do |name, action_config|
49
- format("%<name>-#{NAME_WIDTH}s %<desc>s",
50
- name: "#{name.yellow} #{alias_string_for(action_config)}",
51
- desc: action_config["description"] || action_config["command"]
52
- )
53
- end.sort
54
- end
55
-
56
- def alias_string_for(action_config)
57
- return "[#{action_config["alias"]}]" if action_config["alias"]
58
-
59
- ""
60
- end
61
-
62
- def builtin_enumerator
63
- @builtin_enumerator ||= ::Builtins::Helpers::Enumerator
64
- end
65
- end
66
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Builtins
4
- module Helpers
5
- class DependencyHandler
6
- def initialize(dependency_set)
7
- @dependency_set = dependency_set
8
- end
9
-
10
- def dependencies
11
- return [] unless @dependency_set
12
-
13
- @dependency_set.map do |type, names|
14
- dependencies_for(type, names)
15
- end.flatten.compact
16
- end
17
-
18
- def dependencies_for(type, names)
19
- dependency_class = Dependencies.const_get(type.capitalize.to_sym, false)
20
-
21
- names.map { |name| dependency_class.new(name) }
22
- rescue NameError
23
- Output.error("No way to handle dependencies of type '#{type}'; ignoring.")
24
- end
25
- end
26
- end
27
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'require_all'
4
- require_rel '..'
5
-
6
- module Builtins
7
- module Helpers
8
- class Enumerator
9
- class << self
10
- def names_by_constant
11
- constants_by_name.each_with_object({}) do |(name, const), hash|
12
- if hash.include?(const)
13
- hash[const] << name
14
- else
15
- hash[const] = [name]
16
- end
17
- end
18
- end
19
-
20
- private
21
-
22
- def constants_by_name
23
- @constants_by_name = Builtins.constants.each_with_object({}) do |const_name, hash|
24
- const = Builtins.const_get(const_name, false)
25
-
26
- next unless const.is_a?(Class)
27
-
28
- hash[const_name] = const
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
data/lib/builtins/init.rb DELETED
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'fileutils'
4
-
5
- module Builtins
6
- class Init < Builtin
7
- OPS_YML = "ops.yml"
8
- TEMPLATE_DIR = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "etc"))
9
- OPS_YML_TEMPLATE = File.join(TEMPLATE_DIR, "%<template_name>s.template.yml")
10
- DEFAULT_TEMPLATE_NAME = "ops"
11
-
12
- class << self
13
- def description
14
- "creates an ops.yml file from a template"
15
- end
16
- end
17
-
18
- def run
19
- if File.exist?(OPS_YML)
20
- Output.error("File '#{OPS_YML} exists; not initializing.")
21
-
22
- return false
23
- end
24
-
25
- Output.out("Creating '#{OPS_YML} from template...")
26
- FileUtils.cp(template_path, OPS_YML)
27
-
28
- true
29
- rescue SystemCallError
30
- Output.error(template_not_found_message)
31
- exit 1
32
- end
33
-
34
- private
35
-
36
- def template_name
37
- @args[0]
38
- end
39
-
40
- def template_path
41
- return template_name if template_name && File.exist?(template_name)
42
-
43
- builtin_template_path
44
- end
45
-
46
- def builtin_template_path
47
- format(OPS_YML_TEMPLATE, template_name: template_name || DEFAULT_TEMPLATE_NAME)
48
- end
49
-
50
- def template_name_list
51
- @template_name_list ||= Dir.entries(TEMPLATE_DIR).map do |name|
52
- name.match(/^([^.]*).template.yml/)&.captures&.first
53
- end.compact
54
- end
55
-
56
- def template_not_found_message
57
- <<~MESSAGE
58
- Template '#{template_path} does not exist.
59
- \nValid template names are:
60
- - #{template_name_list.join("\n - ")}\n
61
- MESSAGE
62
- end
63
- end
64
- end
data/lib/builtins/up.rb DELETED
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Builtins
4
- class Up < Common::UpDown
5
- def handle_dependency(dependency)
6
- dependency.meet
7
- end
8
- end
9
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Builtins
4
- class Version < Builtin
5
- class << self
6
- def description
7
- "prints the version of ops that is running"
8
- end
9
- end
10
-
11
- def run
12
- Output.out(::Version.version)
13
-
14
- true
15
- end
16
- end
17
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'English'
4
-
5
- module Dependencies
6
- class Apk < Dependency
7
- def met?
8
- execute("apk info | grep -q '^#{name}'$")
9
- end
10
-
11
- def meet
12
- execute("apk add #{name}")
13
- end
14
-
15
- def unmeet
16
- # do nothing; we don't want to uninstall packages and reinstall them every time
17
- true
18
- end
19
-
20
- def should_meet?
21
- `uname`.chomp == "Linux" && system("which apk", out: File::NULL, err: File::NULL)
22
- end
23
- end
24
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dependencies
4
- class Apt < VersionedDependency
5
- def met?
6
- if versioned?
7
- apt_cache_policy.installed_version == dep_version
8
- else
9
- apt_cache_policy.installed?
10
- end
11
- end
12
-
13
- def meet
14
- if versioned?
15
- execute("#{sudo_string}apt-get install -y #{dep_name}=#{dep_version}")
16
- else
17
- execute("#{sudo_string}apt-get install -y #{name}")
18
- end
19
- end
20
-
21
- def unmeet
22
- # do nothing; we don't want to uninstall packages and reinstall them every time
23
- true
24
- end
25
-
26
- def should_meet?
27
- `uname`.chomp == "Linux" && system("which apt-get", out: File::NULL, err: File::NULL)
28
- end
29
-
30
- private
31
-
32
- def apt_cache_policy
33
- @apt_cache_policy ||= Dependencies::Helpers::AptCachePolicy.new(dep_name)
34
- end
35
-
36
- def sudo_string
37
- return "" if ENV['USER'] == "root" || `whoami` == "root" || Options.get("apt.use_sudo") == false
38
-
39
- "sudo "
40
- end
41
- end
42
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dependencies
4
- class Brew < Dependency
5
- def met?
6
- execute("brew list #{name}")
7
- end
8
-
9
- def meet
10
- execute("brew install #{name}")
11
- end
12
-
13
- def unmeet
14
- # do nothing; we don't want to uninstall packages and reinstall them every time
15
- true
16
- end
17
-
18
- def should_meet?
19
- `uname`.chomp == "Darwin"
20
- end
21
- end
22
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dependencies
4
- class Cask < Brew
5
- def met?
6
- execute("brew list --cask #{name}")
7
- end
8
-
9
- def meet
10
- execute("brew install --cask #{name}")
11
- end
12
- end
13
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dependencies
4
- class Custom < Dependency
5
- class CustomConfigError < StandardError; end
6
-
7
- def initialize(definition)
8
- super
9
- @definition = definition
10
- @name, @config = parse_definition
11
- end
12
-
13
- def met?
14
- false
15
- end
16
-
17
- def always_act?
18
- true
19
- end
20
-
21
- def meet
22
- execute(up_command) if up_command
23
- end
24
-
25
- def unmeet
26
- execute(down_command) if down_command
27
- end
28
-
29
- private
30
-
31
- def up_command
32
- @up_command ||= @definition.is_a?(Hash) ? @config&.dig("up") : name
33
- end
34
-
35
- def down_command
36
- @down_command ||= @config && @config&.dig("down") || nil
37
- end
38
-
39
- def parse_definition
40
- return @definition.first if @definition.is_a?(Hash)
41
-
42
- [@definition.to_s, {}]
43
- end
44
- end
45
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dependencies
4
- class Dir < Dependency
5
- def met?
6
- execute("test -d #{name}")
7
- end
8
-
9
- def meet
10
- execute("mkdir -p #{name}")
11
- end
12
-
13
- def unmeet
14
- # do nothing; we don't want to delete the directory on an `ops down`
15
- true
16
- end
17
-
18
- def should_meet?
19
- true
20
- end
21
- end
22
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dependencies
4
- class Docker < Dependency
5
- def met?
6
- execute("cd #{name} && docker-compose ps | grep -q ' Up '")
7
- end
8
-
9
- def meet
10
- execute("cd #{name} && docker-compose up -d")
11
- end
12
-
13
- def unmeet
14
- execute("cd #{name} && docker-compose down")
15
- end
16
- end
17
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dependencies
4
- class Gem < VersionedDependency
5
- def met?
6
- if versioned?
7
- execute("gem list -i '^#{dep_name}$' -v '#{dep_version}'") if versioned?
8
- else
9
- execute("gem list -i '^#{name}$'")
10
- end
11
- end
12
-
13
- def meet
14
- if versioned?
15
- execute("#{sudo_string}gem install #{user_install_string}'#{dep_name}' -v '#{dep_version}'")
16
- else
17
- execute("#{sudo_string}gem install #{user_install_string}'#{name}'")
18
- end
19
- end
20
-
21
- def unmeet
22
- # do nothing; we don't want to uninstall packages and reinstall them every time
23
- true
24
- end
25
-
26
- private
27
-
28
- def sudo_string
29
- Options.get("gem.use_sudo") ? "sudo " : ""
30
- end
31
-
32
- def user_install_string
33
- Options.get("gem.user_install") ? "--user-install " : ""
34
- end
35
- end
36
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dependencies
4
- module Helpers
5
- class AptCachePolicy
6
- INSTALLED_VERSION_REGEX = / Installed: ([-+.a-z0-9]+)/.freeze
7
-
8
- attr_reader :name
9
-
10
- def initialize(name)
11
- @name = name
12
- end
13
-
14
- def installed_version
15
- version_from_policy_version_line(installed_version_line)
16
- end
17
-
18
- def installed?
19
- !!installed_version
20
- end
21
-
22
- private
23
-
24
- def installed_version_line
25
- apt_cache_lines.find { |line| line.match(/#{INSTALLED_VERSION_REGEX}/) }
26
- end
27
-
28
- def version_from_policy_version_line(line)
29
- return nil if line.nil?
30
-
31
- # E.g.:
32
- # Installed: 7.52.1-5+deb9u7
33
- match = line.match(/#{INSTALLED_VERSION_REGEX}/)
34
-
35
- match.nil? ? nil : match[1]
36
- end
37
-
38
- def apt_cache_lines
39
- @apt_cache_lines ||= `apt-cache policy #{name}`.split("\n")
40
- end
41
- end
42
- end
43
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'English'
4
-
5
- module Dependencies
6
- class Pip < Dependency
7
- DEFAULT_PIP = "python3 -m pip"
8
-
9
- def met?
10
- execute("#{pip} show #{name}")
11
- end
12
-
13
- def meet
14
- execute("#{pip} install #{name}")
15
- end
16
-
17
- def unmeet
18
- # do nothing; we don't want to uninstall packages and reinstall them every time
19
- true
20
- end
21
-
22
- def should_meet?
23
- true
24
- end
25
-
26
- private
27
-
28
- def pip
29
- Options.get("pip.command") || DEFAULT_PIP
30
- end
31
- end
32
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dependencies
4
- class Snap < VersionedDependency
5
- def met?
6
- system("snap list | grep -q \"^name \"")
7
- end
8
-
9
- def meet
10
- execute("#{sudo_string}snap install #{name}")
11
- end
12
-
13
- def unmeet
14
- # do nothing; we don't want to uninstall packages and reinstall them every time
15
- true
16
- end
17
-
18
- def should_meet?
19
- return false unless Options.get("snap.install")
20
- return false unless `uname`.chomp == "Linux"
21
- return false unless system("which snap", out: File::NULL, err: File::NULL)
22
-
23
- true
24
- end
25
-
26
- private
27
-
28
- def sudo_string
29
- return "sudo " unless Options.get("snap.use_sudo") == false
30
- end
31
- end
32
- end
@@ -1,121 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'fileutils'
4
- require 'net/ssh'
5
-
6
- module Dependencies
7
- class Sshkey < Dependency
8
- DEFAULT_KEY_SIZE = 4096
9
- DEFAULT_KEY_ALGO = "rsa"
10
- DEFAULT_KEY_LIFETIME_S = 3600
11
- DEFAULT_KEY_FILE_COMMENT_COMMAND = "$USER@`hostname -s`"
12
-
13
- def met?
14
- # we always need to at least update the key lifetime in the agent
15
- false
16
- end
17
-
18
- def meet
19
- Secrets.load
20
-
21
- Output.warn("\nNo passphrase set for SSH key '#{priv_key_name}'") if passphrase.nil? || passphrase.empty?
22
-
23
- FileUtils.mkdir_p(dir_name) unless File.directory?(dir_name)
24
- generate_key unless File.exist?(priv_key_name) && File.exist?(pub_key_name)
25
- add_key if success? && should_add_key?
26
- end
27
-
28
- def unmeet
29
- true
30
- end
31
-
32
- def should_meet?
33
- true
34
- end
35
-
36
- private
37
-
38
- def generate_key
39
- execute(
40
- "ssh-keygen -b #{opt_key_size} -t #{opt_key_algo} -f #{priv_key_name} -q -N '#{passphrase}' -C '#{key_file_comment}'"
41
- )
42
- end
43
-
44
- def add_key
45
- Net::SSH::Authentication::Agent.connect.add_identity(
46
- unencrypted_key,
47
- key_comment,
48
- lifetime: opt_key_lifetime
49
- )
50
- end
51
-
52
- def should_add_key?
53
- ENV["SSH_AUTH_SOCK"] && opt_add_keys?
54
- end
55
-
56
- def unencrypted_key
57
- Net::SSH::KeyFactory.load_private_key(priv_key_name, passphrase.empty? ? nil : passphrase)
58
- end
59
-
60
- def key_comment
61
- Ops.project_name
62
- end
63
-
64
- def key_file_comment
65
- `echo #{opt_key_file_comment_command}`.chomp
66
- end
67
-
68
- def dir_name
69
- `echo #{File.dirname(name)}`.chomp
70
- end
71
-
72
- def priv_key_name
73
- `echo #{name}`.chomp
74
- end
75
-
76
- def pub_key_name
77
- "#{priv_key_name}.pub"
78
- end
79
-
80
- def opt_key_size
81
- Options.get("sshkey.key_size") || DEFAULT_KEY_SIZE
82
- end
83
-
84
- def opt_key_algo
85
- Options.get("sshkey.key_algo") || DEFAULT_KEY_ALGO
86
- end
87
-
88
- def passphrase
89
- `echo #{opt_passphrase}`.chomp
90
- end
91
-
92
- def opt_passphrase
93
- @opt_passphrase ||= begin
94
- return "$#{Options.get('sshkey.passphrase_var')}" if Options.get("sshkey.passphrase_var")
95
-
96
- output_passphrase_warning if Options.get("sshkey.passphrase")
97
-
98
- Options.get("sshkey.passphrase")
99
- end
100
- end
101
-
102
- def output_passphrase_warning
103
- Output.warn(
104
- "\n'options.sshkey.passphrase' is deprecated and will be removed in a future release. " \
105
- "Use 'options.sshkey.passphrase_var' instead."
106
- )
107
- end
108
-
109
- def opt_add_keys?
110
- Options.get("sshkey.add_keys").nil? ? true : Options.get("sshkey.add_keys")
111
- end
112
-
113
- def opt_key_lifetime
114
- Options.get("sshkey.key_lifetime") || DEFAULT_KEY_LIFETIME_S
115
- end
116
-
117
- def opt_key_file_comment_command
118
- Options.get("sshkey.key_file_comment") || DEFAULT_KEY_FILE_COMMENT_COMMAND
119
- end
120
- end
121
- end