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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0131f82f1965a47c70c80d6d353159844ba315f2fd02c55ce91af2c0f3cf69d1
4
- data.tar.gz: 244e1f3e044e16d1581057f4c98a1ae1264d0b18e632303a75341871c70d64f8
3
+ metadata.gz: ffbfe47eb5ac6fd8b908604cb1409e4b90f5e03761d6f111b53dfd93ecb2d9fe
4
+ data.tar.gz: ce01d34fcab6f08a8b07a41cf7cfe99d3ed96c6ac9a3353f48ebbb65d2c03694
5
5
  SHA512:
6
- metadata.gz: ddd7f8194e1628c659f515335c2bc33294a0cb67d1d9c4a1215509d482fa627f3248b4be9c6cd63465e71914bac6363ae0ced6bc07300da62b7db341d6cec21d
7
- data.tar.gz: 4dadf01f5bbd5a875c2b5440d429c5fde2c90a85677b9e88ce1e2451200e6a82c23d3d6afca067ba73e77e14f312ef7b7f2223c7ad7c10dd48a69be0e4ec2953
6
+ metadata.gz: fd14eed08cc7eb9e38e1bc8c995142b197d27ef8789718a0c8daea0af57f45704c5720fed3e15b7a8f6d0a0021d21e098bd02cd234cfde3ba822804a532bbec5
7
+ data.tar.gz: 27b74a7306b5577f38b1864be03a13fd3eeababf2447a37f317b0a55c5f59c94d648f957f93b010ce981fbb3b161e1889d1b841509d0cd638e7850d143558939
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+
3
+ echo "$SECRET1"
4
+ echo "$SECRET2"
@@ -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(command, args)
7
- @command = command
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
- "#{@command} #{@args.join(' ')}"
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
@@ -1,6 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Builtin
4
+ class << self
5
+ def description
6
+ "no description"
7
+ end
8
+ end
9
+
4
10
  def initialize(args, config)
5
11
  @args = args
6
12
  @config = config
@@ -8,7 +8,13 @@ require 'builtins/helpers/dependency_handler'
8
8
 
9
9
  module Builtins
10
10
  class Down < Builtin
11
- def run
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
@@ -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'] || 'dev'
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
@@ -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.")
@@ -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
@@ -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 defined in local `ops.yml`
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
- @action ||= Action.new(command, @args)
63
- end
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
- raise UnknownActionError, "Unknown action: #{@action_name}"
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, body), alias_hash|
90
- alias_hash[body["alias"]] = body if body.include?("alias")
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__
@@ -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 load_into_environment
9
- secrets['environment'].each do |key, value|
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
@@ -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.1.5
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