ops_team 0.1.5 → 0.2.2
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/print_secrets +4 -0
- data/lib/action.rb +34 -3
- data/lib/builtin.rb +6 -0
- data/lib/builtins/down.rb +7 -1
- data/lib/builtins/env.rb +7 -3
- data/lib/builtins/help.rb +42 -0
- data/lib/builtins/helpers/dependency_handler.rb +1 -1
- data/lib/builtins/init.rb +6 -0
- data/lib/builtins/up.rb +6 -0
- data/lib/builtins/version.rb +32 -0
- data/lib/dependencies/dir.rb +24 -0
- data/lib/environment.rb +21 -0
- data/lib/ops.rb +24 -13
- data/lib/secrets.rb +30 -5
- data/ops_team.gemspec +28 -0
- metadata +7 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffbfe47eb5ac6fd8b908604cb1409e4b90f5e03761d6f111b53dfd93ecb2d9fe
|
4
|
+
data.tar.gz: ce01d34fcab6f08a8b07a41cf7cfe99d3ed96c6ac9a3353f48ebbb65d2c03694
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd14eed08cc7eb9e38e1bc8c995142b197d27ef8789718a0c8daea0af57f45704c5720fed3e15b7a8f6d0a0021d21e098bd02cd234cfde3ba822804a532bbec5
|
7
|
+
data.tar.gz: 27b74a7306b5577f38b1864be03a13fd3eeababf2447a37f317b0a55c5f59c94d648f957f93b010ce981fbb3b161e1889d1b841509d0cd638e7850d143558939
|
data/bin/print_secrets
ADDED
data/lib/action.rb
CHANGED
@@ -1,18 +1,49 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'secrets'
|
4
|
+
|
3
5
|
# represents one action to be performed in the shell
|
4
6
|
# can assemble a command line from a command and args
|
5
7
|
class Action
|
6
|
-
def initialize(
|
7
|
-
@
|
8
|
+
def initialize(config, args, options)
|
9
|
+
@config = config
|
8
10
|
@args = args
|
11
|
+
@options = options
|
9
12
|
end
|
10
13
|
|
11
14
|
def run
|
15
|
+
load_secrets if load_secrets?
|
16
|
+
|
12
17
|
Kernel.exec(to_s)
|
13
18
|
end
|
14
19
|
|
15
20
|
def to_s
|
16
|
-
"#{
|
21
|
+
"#{command} #{@args.join(' ')}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def alias
|
25
|
+
@config["alias"]
|
26
|
+
end
|
27
|
+
|
28
|
+
def command
|
29
|
+
@config["command"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def description
|
33
|
+
@config["description"]
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def load_secrets?
|
39
|
+
@config["load_secrets"]
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_secrets
|
43
|
+
Secrets.new(secrets_file).load
|
44
|
+
end
|
45
|
+
|
46
|
+
def secrets_file
|
47
|
+
`echo -n #{@options&.dig("secrets", "path")}`
|
17
48
|
end
|
18
49
|
end
|
data/lib/builtin.rb
CHANGED
data/lib/builtins/down.rb
CHANGED
@@ -8,7 +8,13 @@ require 'builtins/helpers/dependency_handler'
|
|
8
8
|
|
9
9
|
module Builtins
|
10
10
|
class Down < Builtin
|
11
|
-
|
11
|
+
class << self
|
12
|
+
def description
|
13
|
+
"Stops dependent services listed in ops.yml"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
12
18
|
# TODO: return a success/failure status to the caller
|
13
19
|
unmeet_dependencies
|
14
20
|
end
|
data/lib/builtins/env.rb
CHANGED
@@ -5,14 +5,18 @@ require 'output'
|
|
5
5
|
|
6
6
|
module Builtins
|
7
7
|
class Env < Builtin
|
8
|
+
class << self
|
9
|
+
def description
|
10
|
+
"Prints the current environment, e.g. 'dev', 'production', 'staging', etc."
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
8
14
|
def run
|
9
15
|
Output.print(environment)
|
10
16
|
end
|
11
17
|
|
12
|
-
private
|
13
|
-
|
14
18
|
def environment
|
15
|
-
ENV['environment']
|
19
|
+
ENV['environment']
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'colorize'
|
4
|
+
|
5
|
+
require 'builtin'
|
6
|
+
|
7
|
+
module Builtins
|
8
|
+
class Help < Builtin
|
9
|
+
class << self
|
10
|
+
def description
|
11
|
+
"Displays available builtins and actions"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
Output.out("Builtins:")
|
17
|
+
Output.out(" #{builtins.join("\n ")}")
|
18
|
+
Output.out("")
|
19
|
+
Output.out("Actions:")
|
20
|
+
Output.out(" #{actions.join("\n ")}")
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def builtins
|
26
|
+
builtin_class_names.map do |class_name|
|
27
|
+
description = Builtins.const_get(class_name).description
|
28
|
+
format("%<name>-35s %<desc>s", name: class_name.downcase.to_s.yellow, desc: description)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def builtin_class_names
|
33
|
+
Builtins.constants.select { |c| Builtins.const_get(c).is_a? Class }
|
34
|
+
end
|
35
|
+
|
36
|
+
def actions
|
37
|
+
@config["actions"].map do |name, value|
|
38
|
+
format("%<name>-35s %<desc>s", name: name.yellow, desc: value["description"] || value["command"])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -22,7 +22,7 @@ module Builtins
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def dependencies_for(type, names)
|
25
|
-
dependency_class = Dependencies.const_get(type.capitalize.to_sym)
|
25
|
+
dependency_class = Dependencies.const_get(type.capitalize.to_sym, false)
|
26
26
|
|
27
27
|
names.map { |name| dependency_class.new(name) }
|
28
28
|
rescue NameError
|
data/lib/builtins/init.rb
CHANGED
@@ -12,6 +12,12 @@ module Builtins
|
|
12
12
|
OPS_YML_TEMPLATE = File.join(TEMPLATE_DIR, "%<template_name>s.template.yml")
|
13
13
|
DEFAULT_TEMPLATE_NAME = "ops"
|
14
14
|
|
15
|
+
class << self
|
16
|
+
def description
|
17
|
+
"Creates an ops.yml file from a template"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
15
21
|
def run
|
16
22
|
if File.exist?(OPS_YML)
|
17
23
|
Output.error("File '#{OPS_YML} exists; not initializing.")
|
data/lib/builtins/up.rb
CHANGED
@@ -9,6 +9,12 @@ require 'output'
|
|
9
9
|
|
10
10
|
module Builtins
|
11
11
|
class Up < Builtin
|
12
|
+
class << self
|
13
|
+
def description
|
14
|
+
"Attempts to meet dependencies listed in ops.yml"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
12
18
|
def run
|
13
19
|
# TODO: return a success/failure status to the caller
|
14
20
|
meet_dependencies
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
|
5
|
+
require "output"
|
6
|
+
|
7
|
+
module Builtins
|
8
|
+
class Version < Builtin
|
9
|
+
GEMSPEC_FILE = "#{__dir__}/../../ops_team.gemspec"
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def description
|
13
|
+
"Prints the version of ops that is running"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
unless gemspec
|
19
|
+
Output.error("Unable to load gemspec at '#{GEMSPEC_FILE}")
|
20
|
+
return false
|
21
|
+
end
|
22
|
+
|
23
|
+
Output.out(gemspec.version)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def gemspec
|
29
|
+
@gemspec ||= Gem::Specification.load(GEMSPEC_FILE)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dependency'
|
4
|
+
|
5
|
+
module Dependencies
|
6
|
+
class Dir < Dependency
|
7
|
+
def met?
|
8
|
+
execute("test -d #{name}")
|
9
|
+
end
|
10
|
+
|
11
|
+
def meet
|
12
|
+
execute("mkdir #{name}")
|
13
|
+
end
|
14
|
+
|
15
|
+
def unmeet
|
16
|
+
# do nothing; we don't want to delete the directory on an `ops down`
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def should_meet?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/environment.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Environment
|
4
|
+
def initialize(env_hash)
|
5
|
+
@env_hash = env_hash
|
6
|
+
end
|
7
|
+
|
8
|
+
def set_variables
|
9
|
+
@env_hash.each do |key, value|
|
10
|
+
ENV[key] = value
|
11
|
+
end
|
12
|
+
|
13
|
+
ENV['environment'] = environment
|
14
|
+
end
|
15
|
+
|
16
|
+
def environment
|
17
|
+
return 'dev' if ENV['environment'].nil? || ENV['environment'].empty?
|
18
|
+
|
19
|
+
ENV['environment']
|
20
|
+
end
|
21
|
+
end
|
data/lib/ops.rb
CHANGED
@@ -7,9 +7,10 @@ require 'require_all'
|
|
7
7
|
require 'action'
|
8
8
|
require 'output'
|
9
9
|
require 'options'
|
10
|
+
require 'environment'
|
10
11
|
require_rel "builtins"
|
11
12
|
|
12
|
-
# executes commands
|
13
|
+
# executes commands based on local `ops.yml`
|
13
14
|
class Ops
|
14
15
|
class UnknownActionError < StandardError; end
|
15
16
|
|
@@ -27,6 +28,8 @@ class Ops
|
|
27
28
|
def run
|
28
29
|
exit(INVALID_SYNTAX_EXIT_CODE) unless syntax_valid?
|
29
30
|
|
31
|
+
environment.set_variables
|
32
|
+
|
30
33
|
return builtin.run if builtin
|
31
34
|
|
32
35
|
Output.warn("Running '#{action}' from #{CONFIG_FILE}...")
|
@@ -59,20 +62,16 @@ class Ops
|
|
59
62
|
end
|
60
63
|
|
61
64
|
def action
|
62
|
-
@
|
63
|
-
|
64
|
-
|
65
|
-
def command
|
66
|
-
@command ||= begin
|
67
|
-
return actions[@action_name]["command"] if actions[@action_name]
|
68
|
-
return aliases[@action_name]["command"] if aliases[@action_name]
|
65
|
+
return actions[@action_name] if actions[@action_name]
|
66
|
+
return aliases[@action_name] if aliases[@action_name]
|
69
67
|
|
70
|
-
|
71
|
-
end
|
68
|
+
raise UnknownActionError, "Unknown action: #{@action_name}"
|
72
69
|
end
|
73
70
|
|
74
71
|
def actions
|
75
|
-
config["actions"]
|
72
|
+
config["actions"].transform_values do |config|
|
73
|
+
Action.new(config, @args, action_options)
|
74
|
+
end
|
76
75
|
end
|
77
76
|
|
78
77
|
def config
|
@@ -86,11 +85,23 @@ class Ops
|
|
86
85
|
|
87
86
|
def aliases
|
88
87
|
@aliases ||= begin
|
89
|
-
actions.each_with_object({}) do |(_name,
|
90
|
-
alias_hash[
|
88
|
+
actions.each_with_object({}) do |(_name, action), alias_hash|
|
89
|
+
alias_hash[action.alias] = action if action.alias
|
91
90
|
end
|
92
91
|
end
|
93
92
|
end
|
93
|
+
|
94
|
+
def action_options
|
95
|
+
@action_options ||= @config.dig("options", "actions")
|
96
|
+
end
|
97
|
+
|
98
|
+
def env_vars
|
99
|
+
@config.dig("options", "environment") || {}
|
100
|
+
end
|
101
|
+
|
102
|
+
def environment
|
103
|
+
@environment ||= Environment.new(env_vars)
|
104
|
+
end
|
94
105
|
end
|
95
106
|
|
96
107
|
Ops.new(ARGV).run if $PROGRAM_NAME == __FILE__
|
data/lib/secrets.rb
CHANGED
@@ -1,23 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require 'output'
|
6
|
+
|
3
7
|
class Secrets
|
4
|
-
def initialize(filename)
|
5
|
-
@filename = filename
|
8
|
+
def initialize(filename = "")
|
9
|
+
@filename = filename.empty? ? default_filename : filename
|
6
10
|
end
|
7
11
|
|
8
|
-
def
|
9
|
-
secrets['environment']
|
12
|
+
def load
|
13
|
+
secrets['environment']&.each do |key, value|
|
10
14
|
ENV[key] = value
|
11
15
|
end
|
12
16
|
end
|
13
17
|
|
14
18
|
private
|
15
19
|
|
20
|
+
def default_filename
|
21
|
+
return default_ejson_filename if File.exist?(default_ejson_filename)
|
22
|
+
|
23
|
+
default_json_filename
|
24
|
+
end
|
25
|
+
|
26
|
+
def default_ejson_filename
|
27
|
+
"config/#{environment}/secrets.ejson"
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_json_filename
|
31
|
+
"config/#{environment}/secrets.json"
|
32
|
+
end
|
33
|
+
|
16
34
|
def secrets
|
17
35
|
@secrets ||= JSON.parse(file_contents)
|
36
|
+
rescue JSON::ParserError => e
|
37
|
+
Output.error("Error parsing secrets data: #{e}")
|
38
|
+
{}
|
18
39
|
end
|
19
40
|
|
20
41
|
def file_contents
|
21
|
-
filename.match(/\.ejson$/) ? `ejson decrypt #{filename}` : File.open(filename).read
|
42
|
+
@filename.match(/\.ejson$/) ? `ejson decrypt #{@filename}` : File.open(@filename).read
|
43
|
+
end
|
44
|
+
|
45
|
+
def environment
|
46
|
+
ENV['environment']
|
22
47
|
end
|
23
48
|
end
|
data/ops_team.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'ops_team'
|
5
|
+
s.version = '0.2.2'
|
6
|
+
s.authors = [
|
7
|
+
'nickthecook@gmail.com'
|
8
|
+
]
|
9
|
+
s.date = '2020-05-29'
|
10
|
+
s.summary = 'ops_team handles basic operations tasks for your project, driven by YAML config'
|
11
|
+
s.homepage = 'https://github.com/nickthecook/ops'
|
12
|
+
s.files = Dir[
|
13
|
+
'Gemfile',
|
14
|
+
'bin/*',
|
15
|
+
'lib/*',
|
16
|
+
'etc/*',
|
17
|
+
'lib/builtins/*',
|
18
|
+
'lib/builtins/helpers/*',
|
19
|
+
'lib/dependencies/*',
|
20
|
+
'loader.rb',
|
21
|
+
'ops_team.gemspec'
|
22
|
+
]
|
23
|
+
s.executables << 'ops'
|
24
|
+
s.required_ruby_version = '~> 2.5'
|
25
|
+
s.add_runtime_dependency 'colorize', '~> 0.8', '>= 0.8.1'
|
26
|
+
s.add_runtime_dependency 'require_all', '~> 1.1', '>= 1.1.6'
|
27
|
+
s.license = 'GPL-3.0-only'
|
28
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ops_team
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nickthecook@gmail.com
|
@@ -59,6 +59,7 @@ extra_rdoc_files: []
|
|
59
59
|
files:
|
60
60
|
- Gemfile
|
61
61
|
- bin/ops
|
62
|
+
- bin/print_secrets
|
62
63
|
- bin/tag
|
63
64
|
- etc/ops.template.yml
|
64
65
|
- etc/ruby.template.yml
|
@@ -67,23 +68,28 @@ files:
|
|
67
68
|
- lib/builtin.rb
|
68
69
|
- lib/builtins/down.rb
|
69
70
|
- lib/builtins/env.rb
|
71
|
+
- lib/builtins/help.rb
|
70
72
|
- lib/builtins/helpers/dependency_handler.rb
|
71
73
|
- lib/builtins/init.rb
|
72
74
|
- lib/builtins/up.rb
|
75
|
+
- lib/builtins/version.rb
|
73
76
|
- lib/dependencies/apk.rb
|
74
77
|
- lib/dependencies/apt.rb
|
75
78
|
- lib/dependencies/brew.rb
|
76
79
|
- lib/dependencies/cask.rb
|
77
80
|
- lib/dependencies/custom.rb
|
81
|
+
- lib/dependencies/dir.rb
|
78
82
|
- lib/dependencies/docker.rb
|
79
83
|
- lib/dependencies/gem.rb
|
80
84
|
- lib/dependencies/terraform.rb
|
81
85
|
- lib/dependency.rb
|
86
|
+
- lib/environment.rb
|
82
87
|
- lib/ops.rb
|
83
88
|
- lib/options.rb
|
84
89
|
- lib/output.rb
|
85
90
|
- lib/secrets.rb
|
86
91
|
- loader.rb
|
92
|
+
- ops_team.gemspec
|
87
93
|
homepage: https://github.com/nickthecook/ops
|
88
94
|
licenses:
|
89
95
|
- GPL-3.0-only
|