configmonkey_cli 1.0.0

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 (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +87 -0
  6. data/Rakefile +1 -0
  7. data/VERSION +1 -0
  8. data/bin/configmonkey +9 -0
  9. data/bin/configmonkey.sh +14 -0
  10. data/configmonkey_cli.gemspec +27 -0
  11. data/lib/configmonkey_cli.rb +43 -0
  12. data/lib/configmonkey_cli/application.rb +159 -0
  13. data/lib/configmonkey_cli/application/colorize.rb +22 -0
  14. data/lib/configmonkey_cli/application/configuration.rb +38 -0
  15. data/lib/configmonkey_cli/application/configuration.tpl +0 -0
  16. data/lib/configmonkey_cli/application/core.rb +78 -0
  17. data/lib/configmonkey_cli/application/dispatch.rb +81 -0
  18. data/lib/configmonkey_cli/application/manifest.rb +316 -0
  19. data/lib/configmonkey_cli/application/manifest_actions/base.rb +90 -0
  20. data/lib/configmonkey_cli/application/manifest_actions/chmod.rb +40 -0
  21. data/lib/configmonkey_cli/application/manifest_actions/copy.rb +38 -0
  22. data/lib/configmonkey_cli/application/manifest_actions/custom.rb +52 -0
  23. data/lib/configmonkey_cli/application/manifest_actions/inplace.rb +28 -0
  24. data/lib/configmonkey_cli/application/manifest_actions/invoke.rb +45 -0
  25. data/lib/configmonkey_cli/application/manifest_actions/link.rb +46 -0
  26. data/lib/configmonkey_cli/application/manifest_actions/mkdir.rb +41 -0
  27. data/lib/configmonkey_cli/application/manifest_actions/remove.rb +46 -0
  28. data/lib/configmonkey_cli/application/manifest_actions/rsync.rb +112 -0
  29. data/lib/configmonkey_cli/application/manifest_actions/rtfm.rb +32 -0
  30. data/lib/configmonkey_cli/application/manifest_actions/sync_links.rb +60 -0
  31. data/lib/configmonkey_cli/application/manifest_actions/template.rb +38 -0
  32. data/lib/configmonkey_cli/application/output_helper.rb +30 -0
  33. data/lib/configmonkey_cli/helper.rb +62 -0
  34. data/lib/configmonkey_cli/version.rb +4 -0
  35. metadata +162 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1f88a813de764ee6b33978ab3acf57bd6b4d2c57e0e5352214f6044db20cd327
4
+ data.tar.gz: 1bcbb9340b2a616dbf22e6249ddfd6705f57ee95bc84ae0e70b7bfd421dedfb7
5
+ SHA512:
6
+ metadata.gz: 83f512210d85b8351587412ca44fe9abd4171aea9ae835ff225e238f1c1cd794ad9926962033d1745517256d121d2a629d7cb83f446c3448c426d38deeb6999e
7
+ data.tar.gz: ae82e4e9be85ef140e8dfa0993de9b786330a517ee6acc05e4b5138e4bb542ce654d4b213ac6e88e6b7c656921c067e9fb65f26591b7dab8b9dd60cbfd225575
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ spec/reports
14
+ test/tmp
15
+ test/version_tmp
16
+ tmp
17
+ dev
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dle.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020, Sven Pachnit aka. 2called-chaos
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,87 @@
1
+ # Configmonkey CLI
2
+
3
+ Configmonkey is a very simple tool to "deploy" configurations on servers. Chef/Puppet for the brainless.
4
+
5
+ ---
6
+
7
+ ## Help
8
+ If you need help or have problems [open an issue](https://github.com/2called-chaos/configmonkey_cli/issues/new).
9
+
10
+
11
+ ## Features
12
+
13
+ * …
14
+
15
+
16
+ ## ToDo
17
+
18
+ * logging
19
+ * manifest generation
20
+ * [add something to the list](https://github.com/2called-chaos/configmonkey_cli/issues/new)
21
+
22
+
23
+ ## Requirements
24
+
25
+ * Ruby (>= 2.6)
26
+ * Unixoid OS (such as Ubuntu/Debian, OS X, maybe others), sorry Windows
27
+ * config files
28
+
29
+
30
+ ## Installation
31
+
32
+ * `gem install configmonkey_cli`
33
+ * Go into a folder with your configs (manage them in sub folders)
34
+ * ~~`configmonkey --generate-manifest`~~
35
+ * ~~Edit the created file manifest.rb to fit your needs~~
36
+ * Run `configmonkey -h`
37
+ * Check out the additional features below
38
+
39
+
40
+ ## Usage
41
+
42
+ To get a list of available options invoke Configmonkey with the `--help` or `-h` option:
43
+
44
+ Usage: configmonkey [options]
45
+ # Application options
46
+ --generate-manifest Generates an example manifest in current directory
47
+ -a, --accept accept all defaults
48
+ -b, --no-bell dont ring a bell when asked
49
+ -D, --diff change default diff tool
50
+ -f, --fake-host HOST override hostname
51
+ -i, --in DIR operate from this source directory instead of pwd
52
+ -o, --out DIR operate on this target directory instead of /
53
+ -l, --log [file] Log changes to file, defaults to ~/.configmonkey/logs/configmonkey.log
54
+ -M, --merge change default merge tool
55
+ -n, --dry-run Simulate changes only, does not perform destructive operations
56
+ -y, --yes accept all prompts with yes
57
+ --dev-dump-actions Dump actions and exit
58
+
59
+ # General options
60
+ -d, --debug [lvl=1] Enable debug output
61
+ -m, --monochrome Don't colorize output
62
+ -h, --help Shows this help
63
+ -v, --version Shows version and other info
64
+ -z Do not check for updates on GitHub (with -v/--version)
65
+
66
+ ## Application configuration
67
+
68
+
69
+
70
+
71
+ ## Contributing
72
+
73
+ Contributions are very welcome! Either report errors, bugs and propose features or directly submit code:
74
+
75
+ 1. Fork it
76
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
77
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
78
+ 4. Push to the branch (`git push origin my-new-feature`)
79
+ 5. Create new Pull Request
80
+
81
+ This might be helpful: `./bin/configmonkey.sh -nd 120 -i ./dev/gamesplanet-config -o ./dev/servers/www3 -f www3`
82
+
83
+
84
+ ## Legal
85
+
86
+ * © 2020, Sven Pachnit (www.bmonkeys.net)
87
+ * configmonkey_cli is licensed under the MIT license.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ require "configmonkey_cli"
3
+ begin
4
+ Process.setproctitle("configmonkey_cli")
5
+ ConfigmonkeyCli::Application.dispatch(ENV, ARGV)
6
+ rescue Interrupt
7
+ puts("\nInterrupted")
8
+ exit 1
9
+ end
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+
3
+ # That's __FILE__ in BASH :)
4
+ # From: http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in
5
+ SOURCE="${BASH_SOURCE[0]}"
6
+ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
7
+ MCLDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
8
+ SOURCE="$(readlink "$SOURCE")"
9
+ [[ $SOURCE != /* ]] && SOURCE="$MCLDIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
10
+ done
11
+ PROJECT_ROOT="$( cd -P "$( dirname "$SOURCE" )"/.. && pwd )"
12
+
13
+ # Actually run script
14
+ cd $PROJECT_ROOT && bundle exec ruby bin/configmonkey "$@"
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'configmonkey_cli/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "configmonkey_cli"
8
+ spec.version = ConfigmonkeyCli::VERSION
9
+ spec.authors = ["Sven Pachnit"]
10
+ spec.email = ["sven@bmonkeys.net"]
11
+ spec.summary = %q{Configmonkey CLI - dead simple helper for git based server configs}
12
+ spec.description = %q{Basically chef/puppet for the brainless}
13
+ spec.homepage = "https://github.com/2called-chaos/configmonkey_cli"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "activesupport"
22
+ spec.add_dependency "httparty"
23
+ spec.add_dependency "thor"
24
+ spec.add_development_dependency "pry"
25
+ spec.add_development_dependency "bundler"
26
+ spec.add_development_dependency "rake"
27
+ end
@@ -0,0 +1,43 @@
1
+ STDOUT.sync = true
2
+
3
+ # stdlib
4
+ require "benchmark"
5
+ require "fileutils"
6
+ require "optparse"
7
+ require "open3"
8
+ require "shellwords"
9
+ require "digest/sha1"
10
+
11
+ # 3rd party
12
+ require "active_support"
13
+ require "active_support/core_ext"
14
+ require "active_support/time_with_zone"
15
+ begin ; require "pry" ; rescue LoadError ; end
16
+ require "httparty"
17
+ require "thor"
18
+
19
+ # lib
20
+ require "configmonkey_cli/version"
21
+ require "configmonkey_cli/helper"
22
+ require "configmonkey_cli/application/core"
23
+ require "configmonkey_cli/application/output_helper"
24
+ require "configmonkey_cli/application/colorize"
25
+ require "configmonkey_cli/application/manifest"
26
+ require "configmonkey_cli/application/configuration"
27
+ require "configmonkey_cli/application/dispatch"
28
+ require "configmonkey_cli/application"
29
+
30
+ # actions
31
+ require "configmonkey_cli/application/manifest_actions/base"
32
+ require "configmonkey_cli/application/manifest_actions/chmod"
33
+ require "configmonkey_cli/application/manifest_actions/copy"
34
+ require "configmonkey_cli/application/manifest_actions/custom"
35
+ require "configmonkey_cli/application/manifest_actions/inplace"
36
+ require "configmonkey_cli/application/manifest_actions/invoke"
37
+ require "configmonkey_cli/application/manifest_actions/link"
38
+ require "configmonkey_cli/application/manifest_actions/mkdir"
39
+ require "configmonkey_cli/application/manifest_actions/rsync"
40
+ require "configmonkey_cli/application/manifest_actions/remove"
41
+ require "configmonkey_cli/application/manifest_actions/rtfm"
42
+ require "configmonkey_cli/application/manifest_actions/sync_links"
43
+ require "configmonkey_cli/application/manifest_actions/template"
@@ -0,0 +1,159 @@
1
+ module ConfigmonkeyCli
2
+ class Application
3
+ attr_reader :opts, :connections, :hooks, :env, :argv
4
+ include Helper
5
+ include OutputHelper
6
+ include Colorize
7
+ include Core
8
+ include Dispatch
9
+ include Configuration::AppHelper
10
+
11
+ # =========
12
+ # = Setup =
13
+ # =========
14
+ def self.dispatch *a
15
+ new(*a) do |app|
16
+ app.load_appconfig
17
+ app.parse_params
18
+ begin
19
+ app.dispatch
20
+ app.haltpoint
21
+ rescue Interrupt
22
+ app.abort("Interrupted", 1)
23
+ rescue SystemExit
24
+ app.abort("Aborted", 2)
25
+ ensure
26
+ app.fire(:cm_shutdown)
27
+ app.debug "#{Thread.list.length} threads remain..."
28
+ end
29
+ end
30
+ end
31
+
32
+ def initialize env, argv
33
+ @boot = Time.current
34
+ @env, @argv = env, argv
35
+ @hooks = {}
36
+ @connections = {}
37
+ @monitor = Monitor.new
38
+ @opts = {
39
+ working_directory: Dir.pwd, # -i flag
40
+ target_directory: "/", # -o flag
41
+ hostname: `hostname`.chomp, # -f flag
42
+ diff_tool: nil, # -D flag
43
+ merge_tool: nil, # -M flag
44
+ bell: true, # -b flag
45
+ default_accept: false, # -a flag
46
+ default_yes: false, # -y flag
47
+ dispatch: :index, # (internal) action to dispatch
48
+ simulation: false, # -n flag
49
+ check_for_updates: true, # -z flag
50
+ colorize: true, # -m flag
51
+ debug: false, # -d flag
52
+ # silent: false, # -s flag
53
+ # quiet: false, # -q flag
54
+ stdout: STDOUT, # (internal) STDOUT redirect
55
+ }
56
+ init_params
57
+ yield(self)
58
+ end
59
+
60
+ def find_diff_tool
61
+ [
62
+ opts[:diff_tool],
63
+ ENV["CM_DIFF"],
64
+ ENV["THOR_DIFF"],
65
+ ENV["RAILS_DIFF"],
66
+ "colordiff",
67
+ "git diff --no-index",
68
+ "vim -d",
69
+ "diff -u",
70
+ ].compact.each do |cmd|
71
+ if hit = `which #{cmd.split(" ").first}`.chomp.presence
72
+ debug "§diff-using:(#{hit})#{cmd}"
73
+ return cmd
74
+ else
75
+ debug "§diff-not-found:#{cmd}", 105
76
+ end
77
+ end
78
+ end
79
+
80
+ def find_merge_tool
81
+ [
82
+ opts[:merge_tool],
83
+ ENV["CM_MERGE"],
84
+ ENV["THOR_MERGE"],
85
+ (`git config merge.tool`.chomp rescue nil),
86
+ "vim -d",
87
+ "diff -u",
88
+ ].compact.each do |cmd|
89
+ if hit = `which #{cmd.split(" ").first}`.chomp.presence
90
+ debug "§merge-using:(#{hit})#{cmd}"
91
+ return cmd
92
+ else
93
+ debug "§merge-not-found:#{cmd}", 105
94
+ end
95
+ end
96
+ end
97
+
98
+ def to_s
99
+ "#<ConfigmonkeyCli::Application @boot=#{@boot} @opts=#{@opts} @running=#{@running}>"
100
+ end
101
+
102
+ def init_params
103
+ @optparse = OptionParser.new do |opts|
104
+ opts.banner = "Usage: configmonkey [options]"
105
+
106
+ opts.separator(c "# Application options", :blue)
107
+ opts.on("--generate-manifest", "Generates an example manifest in current directory") { @opts[:dispatch] = :generate_manifest }
108
+ opts.on("-a", "--accept", "accept all defaults") { @opts[:default_accept] = true }
109
+ opts.on("-b", "--no-bell", "dont ring a bell when asked") { @opts[:bell] = false }
110
+ opts.on("-D", "--diff", "change default diff tool") {|s| @opts[:diff_tool] = s }
111
+ opts.on("-f", "--fake-host HOST", "override hostname") {|s| @opts[:hostname] = s }
112
+ opts.on("-i", "--in DIR", "operate from this source directory instead of pwd") {|s| @opts[:working_directory] = s }
113
+ opts.on("-o", "--out DIR", "operate on this target directory instead of /") {|s| @opts[:target_directory] = s }
114
+ opts.on("-l", "--log [file]", "Log changes to file, defaults to ~/.configmonkey/logs/configmonkey.log") {|s| @opts[:logfile] = s || logger_filename }
115
+ opts.on("-M", "--merge", "change default merge tool") {|s| @opts[:merge_tool] = s }
116
+ opts.on("-n", "--dry-run", "Simulate changes only, does not perform destructive operations") { @opts[:simulation] = true }
117
+ opts.on("-y", "--yes", "accept all prompts with yes") { @opts[:default_yes] = true }
118
+ opts.on( "--dev-dump-actions", "Dump actions and exit") { @opts[:dev_dump_actions] = true }
119
+ # opts.on("-q", "--quiet", "Only print errors") { @opts[:quiet] = true }
120
+
121
+ opts.separator("\n" << c("# General options", :blue))
122
+ opts.on("-d", "--debug [lvl=1]", Integer, "Enable debug output") {|l| @opts[:debug] = l || 1 }
123
+ opts.on("-m", "--monochrome", "Don't colorize output") { @opts[:colorize] = false }
124
+ opts.on("-h", "--help", "Shows this help") { @opts[:dispatch] = :help }
125
+ opts.on("-v", "--version", "Shows version and other info") { @opts[:dispatch] = :info }
126
+ opts.on("-z", "Do not check for updates on GitHub (with -v/--version)") { @opts[:check_for_updates] = false }
127
+ end
128
+ end
129
+
130
+ def parse_params
131
+ @optparse.parse!(@argv)
132
+
133
+ # resolve diff/merge tool
134
+ @opts[:diff_tool] = find_diff_tool
135
+ @opts[:merge_tool] = find_merge_tool
136
+
137
+ # thor bell
138
+ ENV['THOR_ASK_BELL'] = "true" if @opts[:bell]
139
+
140
+ # thor no-colors
141
+ ENV['NO_COLOR'] = "true" if !@opts[:colorize]
142
+
143
+ # thor diff-tool
144
+ ENV['THOR_DIFF'] = opts[:diff_tool] if @opts[:diff_tool]
145
+ rescue OptionParser::ParseError => e
146
+ abort(e.message)
147
+ dispatch(:help)
148
+ exit 1
149
+ end
150
+
151
+ def sync &block
152
+ @monitor.synchronize(&block)
153
+ end
154
+
155
+ def running?
156
+ @running
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,22 @@
1
+ module ConfigmonkeyCli
2
+ class Application
3
+ module Colorize
4
+ COLORMAP = {
5
+ black: 30,
6
+ red: 31,
7
+ green: 32,
8
+ yellow: 33,
9
+ blue: 34,
10
+ magenta: 35,
11
+ cyan: 36,
12
+ white: 37,
13
+ }
14
+
15
+ def colorize str, color = :yellow
16
+ ccode = COLORMAP[color.to_sym] || raise(ArgumentError, "Unknown color #{color}!")
17
+ @opts[:colorize] ? "\e[#{ccode}m#{str}\e[0m" : "#{str}"
18
+ end
19
+ alias_method :c, :colorize
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,38 @@
1
+ module ConfigmonkeyCli
2
+ class Application
3
+ class Configuration
4
+ module AppHelper
5
+ def cm_cfg_path
6
+ ENV["CM_CFGDIR"].presence || File.expand_path("~/.configmonkey")
7
+ end
8
+
9
+ def cm_cfg_configfile
10
+ "#{cm_cfg_path}/config.rb"
11
+ end
12
+
13
+ def load_appconfig
14
+ return unless File.exist?(cm_cfg_configfile)
15
+ eval File.read(cm_cfg_configfile, encoding: "utf-8"), binding, cm_cfg_configfile
16
+ end
17
+
18
+ def generate_manifest directory
19
+ #FileUtils.mkdir_p(config_directory)
20
+ #File.open(config_filename(name), "w", encoding: "utf-8") do |f|
21
+ # f << File.read("#{File.dirname(__FILE__)}/configuration.tpl", encoding: "utf-8")
22
+ #end
23
+ end
24
+
25
+ def load_and_execute_manifest
26
+ manifest = Manifest.new(self, File.realpath(File.expand_path(opts[:working_directory])), @argv[0])
27
+ if opts[:dev_dump_actions]
28
+ manifest._dump!
29
+ elsif opts[:simulation]
30
+ manifest._simulate!
31
+ else
32
+ manifest._execute!
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end