puppet-masterless 0.1.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.
- checksums.yaml +7 -0
- data/bin/puppet-masterless +180 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f25c87151bb067f0180ff521e3d9321de1bde8c6
|
4
|
+
data.tar.gz: 27e83b426523ea8d6424f44826d9ce552ae20aa6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 54f080712152dad70216e838c52664572e945e25fea3f15a4507a8208cece077cd087fbdc6c19a42b7e3c9f7b2db59e180b8bada031bb577dbe0ef8d7de2017c
|
7
|
+
data.tar.gz: bdab25968892f155f6fb37e0ebb462a975db8476c36978572b01463561a57ec82b2363ca851357dfb7954c8094d47509fcb39a75e768f4a1878d93e3c8e3c478
|
@@ -0,0 +1,180 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Usage: puppet-masterless <subcommand> [<argument> ...] [-- puppet arguments ...]
|
4
|
+
#
|
5
|
+
# Applies a local puppet project to a remote host.
|
6
|
+
#
|
7
|
+
# Available subcommands:
|
8
|
+
#
|
9
|
+
# package
|
10
|
+
# apply
|
11
|
+
#
|
12
|
+
# Available arguments:
|
13
|
+
#
|
14
|
+
# confdir <directory>
|
15
|
+
# hiera_config <file>
|
16
|
+
# manifest <file>
|
17
|
+
# modulepath <directory>
|
18
|
+
# puppet <executable>
|
19
|
+
# to <hostname>
|
20
|
+
# as <username>
|
21
|
+
# file <file>
|
22
|
+
#
|
23
|
+
# At least <confdir> must be specified.
|
24
|
+
#
|
25
|
+
|
26
|
+
require 'shellwords'
|
27
|
+
|
28
|
+
module PuppetMasterless
|
29
|
+
ARCHIVE_NAME = 'puppet-masterless'
|
30
|
+
ARCHIVE_OPTIONS = '--ignore-failed-read --exclude-vcs'
|
31
|
+
DEFAULT_PUPPET = 'puppet'
|
32
|
+
REMOTE_USER = 'root'
|
33
|
+
REMOTE_WORKDIR = '/tmp'
|
34
|
+
|
35
|
+
class Main
|
36
|
+
def initialize
|
37
|
+
@files = []
|
38
|
+
@args = []
|
39
|
+
@path = ARCHIVE_NAME
|
40
|
+
@puppet = DEFAULT_PUPPET
|
41
|
+
@user = REMOTE_USER
|
42
|
+
@workdir = REMOTE_WORKDIR
|
43
|
+
@output = "#{ARCHIVE_NAME}.sh"
|
44
|
+
end
|
45
|
+
|
46
|
+
def banner
|
47
|
+
File.read(__FILE__).lines[1..23].map { |s| s.gsub(/^# ?/, '') }
|
48
|
+
end
|
49
|
+
|
50
|
+
def usage n = 1
|
51
|
+
STDERR.puts(banner)
|
52
|
+
exit(n)
|
53
|
+
end
|
54
|
+
|
55
|
+
def collect args
|
56
|
+
while word = args.shift
|
57
|
+
case word
|
58
|
+
when 'with', 'and'
|
59
|
+
when 'confdir' then @confdir = args.shift
|
60
|
+
when 'manifest' then @manifest = args.shift
|
61
|
+
when 'modulepath' then @modulepath = args.shift
|
62
|
+
when 'hiera_config' then @hiera_config = args.shift
|
63
|
+
when 'puppet' then @puppet = args.shift
|
64
|
+
when 'to' then @hostname = args.shift
|
65
|
+
when 'as' then @user = args.shift
|
66
|
+
when 'file' then @files << args.shift
|
67
|
+
when '--', nil then @args = args.slice!(0..-1)
|
68
|
+
else fail 'Invalid argument: ' << word
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def validate
|
74
|
+
fail 'No confdir specified' unless @confdir
|
75
|
+
fail 'No puppet specified' unless @puppet
|
76
|
+
|
77
|
+
@manifest ||= File.join(@confdir, 'manifests')
|
78
|
+
@modulepath ||= File.join(@confdir, 'modules')
|
79
|
+
@hiera_config ||= File.join(@confdir, 'hiera.yaml')
|
80
|
+
|
81
|
+
fail 'No such confdir: ' << @confdir unless File.directory?(@confdir)
|
82
|
+
fail 'No such manifest: ' << @manifest unless File.exist?(@manifest)
|
83
|
+
|
84
|
+
@modulepath = nil unless File.directory?(@modulepath)
|
85
|
+
@hiera_config = nil unless File.file?(@hiera_config)
|
86
|
+
end
|
87
|
+
|
88
|
+
def package
|
89
|
+
create_distribution
|
90
|
+
end
|
91
|
+
|
92
|
+
def apply
|
93
|
+
if @hostname
|
94
|
+
create_distribution
|
95
|
+
apply_remote
|
96
|
+
else
|
97
|
+
apply_local
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def archive_command
|
104
|
+
"tar -czf- #{ARCHIVE_OPTIONS} --transform 's|^|#{@path.gsub("'", "'\''")}/|' \
|
105
|
+
#{@files.shelljoin} \
|
106
|
+
#{@manifest.shellescape} \
|
107
|
+
#{@modulepath.shellescape if @modulepath} \
|
108
|
+
#{@hiera_config.shellescape if @hiera_config}"
|
109
|
+
end
|
110
|
+
|
111
|
+
def local_apply_command
|
112
|
+
command = "exec #{@puppet} apply #{@manifest.shellescape} --verbose --show_diff --color true --confdir #{@confdir.shellescape}"
|
113
|
+
command << ' --modulepath ' << @modulepath.shellescape if @modulepath
|
114
|
+
command << ' --hiera_config ' << @hiera_config.shellescape if @hiera_config
|
115
|
+
command << ' ' << @args.shelljoin
|
116
|
+
end
|
117
|
+
|
118
|
+
def remote_apply_command
|
119
|
+
"sudo -u #{@user.shellescape} #{@workdir.shellescape}/#{@output.shellescape}"
|
120
|
+
end
|
121
|
+
|
122
|
+
def remote_cleanup_command
|
123
|
+
"sudo -u #{@user.shellescape} rm -f #{@workdir.shellescape}/#{@output.shellescape} -r #{@workdir.shellescape}/#{@path.shellescape}"
|
124
|
+
end
|
125
|
+
|
126
|
+
def apply_local
|
127
|
+
STDERR.puts('Notice: Applying locally')
|
128
|
+
fail 'Apply command failed' unless system(local_apply_command)
|
129
|
+
end
|
130
|
+
|
131
|
+
def apply_remote
|
132
|
+
STDERR.puts('Notice: Copying to ' << @hostname)
|
133
|
+
fail 'Copy command failed' unless system("scp -q #{@output.shellescape} #{@hostname.shellescape}:#{@workdir.shellescape}")
|
134
|
+
STDERR.puts('Notice: Applying to ' << @hostname)
|
135
|
+
fail 'Apply command failed' unless system("ssh -q -t #{@hostname.shellescape} #{remote_apply_command.shellescape}")
|
136
|
+
ensure
|
137
|
+
system("ssh -q -t #{@hostname.shellescape} #{remote_cleanup_command.shellescape}")
|
138
|
+
end
|
139
|
+
|
140
|
+
def create_distribution
|
141
|
+
STDERR.puts("Notice: Creating distribution")
|
142
|
+
|
143
|
+
File.open(@output, 'w') do |o|
|
144
|
+
o.puts("#!/bin/sh -e")
|
145
|
+
o.puts("sed '0,/^# EOF$/d' \"$0\" | tar -xzf-")
|
146
|
+
o.puts("cd #{@path.shellescape}")
|
147
|
+
o.puts(local_apply_command)
|
148
|
+
o.puts("exit 1")
|
149
|
+
o.puts("# EOF")
|
150
|
+
o.chmod(0755)
|
151
|
+
end
|
152
|
+
|
153
|
+
unless system(archive_command << ' >> ' << @output.shellescape)
|
154
|
+
fail 'Archive command failed: ' << archive_command
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
main = PuppetMasterless::Main.new
|
161
|
+
|
162
|
+
begin
|
163
|
+
case ARGV.shift
|
164
|
+
when 'package'
|
165
|
+
main.collect(ARGV)
|
166
|
+
main.validate
|
167
|
+
main.package
|
168
|
+
when 'apply'
|
169
|
+
main.collect(ARGV)
|
170
|
+
main.validate
|
171
|
+
main.apply
|
172
|
+
when '-h', '--help', nil
|
173
|
+
main.usage(0)
|
174
|
+
else
|
175
|
+
main.usage(1)
|
176
|
+
end
|
177
|
+
rescue => e
|
178
|
+
STDERR.puts("Error: #{File.basename($0)}: #{e.message}")
|
179
|
+
exit(1)
|
180
|
+
end
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: puppet-masterless
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Evan Hanson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-05 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Packages and optionally applies a multi-file Puppet project to a remote
|
14
|
+
host via SSH.
|
15
|
+
email: evanh@catalyst.net.nz
|
16
|
+
executables:
|
17
|
+
- puppet-masterless
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- bin/puppet-masterless
|
22
|
+
homepage: https://gitlab.wgtn.cat-it.co.nz/devtools/puppet-masterless
|
23
|
+
licenses:
|
24
|
+
- GPLv3
|
25
|
+
metadata: {}
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 2.6.12
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: Apply a local puppet project to a remote host
|
46
|
+
test_files: []
|