pupistry 0.0.1
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/README.md +296 -0
- data/bin/pupistry +177 -0
- data/lib/pupistry.rb +8 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2c47a743b2bf72dc35a18a04e4c907029773f9cd
|
4
|
+
data.tar.gz: 0ffd31d0773fac92db4989fcd52bafb4b25e2215
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 36fa8ed2a0f3b0fc34d548649582143193fa78e29420bda0f69d5a0c27488c93e4f96a4c102cdcc533cdf9f2414ba8bbb75c28da8363822c59ff8b386987a750
|
7
|
+
data.tar.gz: 715fa89d66398222226527be295da1532d17c9f32a35e2d1d878ac7564a5f3cb5a3632f819cdd6a052d1e3fefed4e6de6381549591904a8014b411219baa29ee
|
data/README.md
ADDED
@@ -0,0 +1,296 @@
|
|
1
|
+
# WORK IN PROGRESS
|
2
|
+
|
3
|
+
This project is currently in progress and not all of this documentation reflects
|
4
|
+
where it is really at. Use this at your own peril/madness.
|
5
|
+
|
6
|
+
# pupistry
|
7
|
+
|
8
|
+
Pupistry (puppet + artistry) is a solution for implementing reliable and secure
|
9
|
+
masterless puppet deployments by taking Puppet modules assembled by r10k and
|
10
|
+
generating compresed and signed archives for distribution to the masterless
|
11
|
+
servers.
|
12
|
+
|
13
|
+
Pupistry builds on the functionality offered by the r10k workflow but rather
|
14
|
+
than requiring the implementing of site-specific custom bootstrap and custom
|
15
|
+
workflow mechanisms, Pupistry executes r10k, assembles the combined modules
|
16
|
+
and then generates a compress artifact file. It then signs the artifact with
|
17
|
+
GPG and uploads it into an Amazon S3 bucket along with a manifest file.
|
18
|
+
|
19
|
+
The masterless Puppet machines then just run a Pupistry job which checks for a
|
20
|
+
new version of the manifest file. If there is, it downloads the new artifact
|
21
|
+
and does a GPG validation before applying it and running Puppet. To make life
|
22
|
+
even easier, Pupistry will even spit out bootstrap files for your platform
|
23
|
+
which sets up each server from scratch to pull and run the artifacts.
|
24
|
+
|
25
|
+
Essentially Pupistry is intended to be a robust solution for masterless Puppet
|
26
|
+
deployments and makes it trivial for beginners to get started with Puppet.
|
27
|
+
|
28
|
+
|
29
|
+
# Why Pupistry?
|
30
|
+
|
31
|
+
Masterless Puppet is a great solution for anyone wanting to avoid scaling issues
|
32
|
+
and risk of centralised failure due to a central Puppet master, but it does bring
|
33
|
+
a number of issues with it.
|
34
|
+
|
35
|
+
1. Having to setup deployer keys to every git repo used is a maintainance headache. Pupistry means only your workstation needs access, which presumably will have access to most/all repos already.
|
36
|
+
2. Your system build success is dependent on all the git repos you've used, including any third parties that could vanish. A single missing or broken repo could prevent autoscaling or new machine builds at a critical time. Pupistry's use of artifact files prevents surprises - if you can hit S3, you're sorted.
|
37
|
+
3. It is easy for malicious code in the third party repos to slip in without noticing. Even if the author themselves is honest, not all repos have proper security like two-factor. Pupistry prevents surprise updates of modules and also has an easy diff feature to see what changed since you last generated an artifact.
|
38
|
+
4. Puppet masterless tends to be implemented in many different ways using everyone's own hacky scripts. Pupistry's goal is to create a singular standard/approach to masterless, in the same way that r10k created a standard approach to git-based Puppet workflows. And this makes things easy - install Pupistry, add the companion Puppet module and run the bootstrap script. Easy!
|
39
|
+
5. No dodgy cronjobs running r10k and Puppet in weird ways. A simple clean agent with daemon or run-once functionality.
|
40
|
+
6. Performance - Go from 30+ seconds r10k update checks to 2 second Pupistry update checks. And when there is a change, it's a fast efficent compressed file download from S3 rather than pulling numerious git repos.
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
# Usage
|
45
|
+
|
46
|
+
## Building new artifacts
|
47
|
+
|
48
|
+
Build a new artifact:
|
49
|
+
|
50
|
+
pupistry build
|
51
|
+
|
52
|
+
Note that artifact builds are done from the upstream git repos, so if you
|
53
|
+
have made changes, remember to git push first before generating. The tool will
|
54
|
+
remind you if it detects nothing has changed since the last run.
|
55
|
+
|
56
|
+
Once your artifact is built, you can double check what has changed in the
|
57
|
+
Puppet modules since the last run with:
|
58
|
+
|
59
|
+
pupistry diff
|
60
|
+
|
61
|
+
|
62
|
+
Finally when you're happy, push it to S3 to be delivered to all your servers.
|
63
|
+
If you have gpg signing enabled, it will ask you to sign here.
|
64
|
+
|
65
|
+
pupistry push
|
66
|
+
|
67
|
+
|
68
|
+
## Bootstrapping nodes
|
69
|
+
|
70
|
+
You need to bootstrap your masterless nodes, which involves installing Pupistry
|
71
|
+
and setting up Puppet configuration accordingly.
|
72
|
+
|
73
|
+
pupistry bootstrap
|
74
|
+
|
75
|
+
pupistry boostrap --template rhel7
|
76
|
+
|
77
|
+
|
78
|
+
You generally can run this on a new non-Puppetised machine, or into the user
|
79
|
+
data field of most cloud providers like AWS or Digital Ocean.
|
80
|
+
|
81
|
+
|
82
|
+
## Running Puppet on target nodes
|
83
|
+
|
84
|
+
Check what is going to be applied (Puppet in --noop mode)
|
85
|
+
|
86
|
+
pupistry apply --noop
|
87
|
+
|
88
|
+
|
89
|
+
Apply the current Puppet manifests:
|
90
|
+
|
91
|
+
pupistry apply
|
92
|
+
|
93
|
+
Specify an alternative environment:
|
94
|
+
|
95
|
+
pupistry apply --environment staging
|
96
|
+
|
97
|
+
|
98
|
+
Run pupistry as a system daemon. When you use the companion Puppet module, a
|
99
|
+
system init file gets installed that sets this daemon up for you automatically.
|
100
|
+
|
101
|
+
pupistry apply --daemon
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
# Installation
|
106
|
+
|
107
|
+
## 1. Application
|
108
|
+
|
109
|
+
First install Pupistry onto your workstation. You can make pupistry generate
|
110
|
+
you a config file if you've never used it before
|
111
|
+
|
112
|
+
gem install pupistry
|
113
|
+
pupistry setup
|
114
|
+
|
115
|
+
Alternatively if you like living on the edge, download this repository and run:
|
116
|
+
|
117
|
+
gembuild pupistry.gemspec
|
118
|
+
gem install pupistry-VERSION.gem
|
119
|
+
pupistry setup
|
120
|
+
|
121
|
+
|
122
|
+
## 2. S3 Bucket
|
123
|
+
|
124
|
+
Pupistry uses S3 for storing and pulling the artifact files. You need to
|
125
|
+
configure the following:
|
126
|
+
|
127
|
+
* A *private* S3 bucket (you'll get this by default).
|
128
|
+
* An IAM account with access to write that bucket (for your build workstation)
|
129
|
+
* An IAM account with access to read that bucket (for your servers)
|
130
|
+
|
131
|
+
If you're not already using IAM with your AWS account you want to be - your
|
132
|
+
servers should only ever have read access to the bucket and only your build
|
133
|
+
workstation should be permitted to write new artifacts. IE, don't share your
|
134
|
+
AWS root account around the place. :-)
|
135
|
+
|
136
|
+
Note that if you're running EC2 instances and using IAM roles, you can avoid
|
137
|
+
needing to create explicit IAM credentials for the agents/servers.
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
## 3. Helper Puppet Module
|
142
|
+
|
143
|
+
Whilst you can use Pupistry to roll out any particular design of Puppet
|
144
|
+
manifests, you will save yourself a lot of pain by also including the Pupistry
|
145
|
+
companion Puppet module in your manifests.
|
146
|
+
|
147
|
+
The companion Puppet module will configure Pupistry for you, including setting
|
148
|
+
up the system service and configuring Puppet and Hiera correctly for masterless
|
149
|
+
operation.
|
150
|
+
|
151
|
+
You can fetch the module from:
|
152
|
+
https://github.com/jethrocarr/pupistry-puppet
|
153
|
+
|
154
|
+
If you're doing r10k and Puppet masterless from scratch, this is probably
|
155
|
+
something you want to make life easy.
|
156
|
+
|
157
|
+
|
158
|
+
## 4. Bootstrapping Nodes
|
159
|
+
|
160
|
+
No need for manual configuration of your servers/nodes, you just need to build
|
161
|
+
your first artifact with Pupistry (`pupistry build && pupistry push`) and then
|
162
|
+
generate a bootstrap script for your particular OS with `pupistry bootstrap`
|
163
|
+
|
164
|
+
The bootstrap script will:
|
165
|
+
1. Install Puppet and Pupistry for the particular OS.
|
166
|
+
2. Download the latest artifact
|
167
|
+
3. Trigger a Puppet run to build your server.
|
168
|
+
|
169
|
+
Once done, it's up to your Puppet manifests to build your machine how you want
|
170
|
+
it - enjoy!
|
171
|
+
|
172
|
+
|
173
|
+
|
174
|
+
# Tutorials
|
175
|
+
|
176
|
+
If you're looking for a more complete introduction to doing masterless Puppet
|
177
|
+
and want to use Pupistry, check out a tutorial by the author:
|
178
|
+
|
179
|
+
TUTORIAL LINK HERE
|
180
|
+
|
181
|
+
By following this tutorial you can go from nothing, to having a complete up
|
182
|
+
and running masterless Puppet environment using Pupistry. It covers the very
|
183
|
+
basics of setting up your r10k environment.
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
|
188
|
+
# Caveats & Future Plans
|
189
|
+
|
190
|
+
## Use r10k
|
191
|
+
|
192
|
+
Currently only an r10k workflow is supported. Pull requests for others (eg
|
193
|
+
Librarian Puppet) are welcome, but it's not a priority for this author as r10k
|
194
|
+
is working nicely.
|
195
|
+
|
196
|
+
|
197
|
+
## Bootstrap Functionality
|
198
|
+
|
199
|
+
Currently Pupistry only supports generation of bootstrap for CentOS 7 & Ubuntu
|
200
|
+
14.04. Other distributions will be added, but it may take time to get to your
|
201
|
+
particular favourite distribution.
|
202
|
+
|
203
|
+
Note that it isn't a show stopper if support for your platform of choice
|
204
|
+
doesn't yet exist - you can use pupistry with pretty much any nix platform,
|
205
|
+
you'll just not have the handy advantage of automatically generated bootstrap
|
206
|
+
for your servers.
|
207
|
+
|
208
|
+
If you do customise it for a different platform, pull requests are VERY
|
209
|
+
welcome, I'll add pretty much any OS if you write a decent bootstrap template
|
210
|
+
for it.
|
211
|
+
|
212
|
+
|
213
|
+
## Continious Deployment
|
214
|
+
|
215
|
+
A lot of what Pupistry does can also be accomplished by various home-grown
|
216
|
+
Continious Deployment (CD) solutions using platforms like Jenkins or Bamboo. CD
|
217
|
+
is an excellent approach for larger organisations, but Pupistry has been
|
218
|
+
designed for both large and small users so does not mandate it.
|
219
|
+
|
220
|
+
It would be possible to use Pupistry as part of your CD process and if you
|
221
|
+
decide to do so, a pull request to better support CD systems out-of-the-box
|
222
|
+
would be welcome.
|
223
|
+
|
224
|
+
|
225
|
+
## Hiera Security Still Sucks
|
226
|
+
|
227
|
+
In a standard Puppet master situation, the Puppet master parses the Hiera data
|
228
|
+
and then passes only the values that apply to a particular host to it. But with
|
229
|
+
masterless Puppet, all machines get a full copy of Hiera data, which could be a
|
230
|
+
major issue if one box gets expoited and the contents leaked. Generally it goes
|
231
|
+
against good practise and damanges the isolation ability of VMs if you give all
|
232
|
+
the VMs enough information to do some serious damage to themselves.
|
233
|
+
|
234
|
+
Pupistry does not yet have any solution for it and it remains a fundamental
|
235
|
+
limitation of the Puppet masterless approach. Longer term, we could potentially
|
236
|
+
craft a solution that customises the artifacts per-machine to fix this security
|
237
|
+
gap, but there's no proper solution currently.
|
238
|
+
|
239
|
+
If you have an environment where you need to send lots of sensitive values to
|
240
|
+
your servers, a traditional master-full Puppet environment may be a better
|
241
|
+
solution for this reason. But if you can architect to avoid this or have no
|
242
|
+
critical secrets in Hiera, Pupistry should be good for you.
|
243
|
+
|
244
|
+
|
245
|
+
## PuppetDB
|
246
|
+
|
247
|
+
There's nothing stopping you from using PuppetDB other than Pupistry has no
|
248
|
+
automatic setup hooks in the bootstrap config. Pull requests to support
|
249
|
+
PuppetDB for masterless machines are welcome, although masterless users tend
|
250
|
+
to want to avoid dependencies on a central point.
|
251
|
+
|
252
|
+
|
253
|
+
## Windows
|
254
|
+
|
255
|
+
No idea whether this works under Windows, or what would be required to make it
|
256
|
+
do so. Again, pull requests always welcome but it's not a priority for the
|
257
|
+
author.
|
258
|
+
|
259
|
+
|
260
|
+
|
261
|
+
# Developing
|
262
|
+
|
263
|
+
When developing Pupistry, you can run the git repo copy with:
|
264
|
+
|
265
|
+
ruby -Ilib/ -r rubygems bin/pupistry
|
266
|
+
|
267
|
+
By default Pupistry will try to load a settings.yaml file in the current
|
268
|
+
working directory, before then trying ~/.pupistry/settings.yaml and then
|
269
|
+
finally /etc/pupistry/settings.yaml. You can also override with --config.
|
270
|
+
|
271
|
+
Add --verbose for additional debugging information.
|
272
|
+
|
273
|
+
|
274
|
+
# Contributions
|
275
|
+
|
276
|
+
Pull requests are very welcome. Pupistry is a very young app and there is
|
277
|
+
plenty of work that can be done to improve it's code quality, enhance existing
|
278
|
+
features and add handy new features. Constructive feedback/requests via the
|
279
|
+
issue tracker is fine, but pull requests speak louder than words. :-)
|
280
|
+
|
281
|
+
If you find a bug or need support, please use the issue tracker rather than
|
282
|
+
personal emails to the author.
|
283
|
+
|
284
|
+
|
285
|
+
# Author
|
286
|
+
|
287
|
+
Pupistry is developed by Jethro Carr. Blog posts about Pupistry and new
|
288
|
+
features can be found at http://www.jethrocarr.com/tag/pupistry
|
289
|
+
|
290
|
+
Beer welcome.
|
291
|
+
|
292
|
+
|
293
|
+
# License
|
294
|
+
|
295
|
+
Pupistry is licensed under the Apache License, Version 2.0.
|
296
|
+
|
data/bin/pupistry
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Lancher for Pupistry CLI
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'thor'
|
6
|
+
require 'logger'
|
7
|
+
require 'pupistry'
|
8
|
+
|
9
|
+
# Ensure all output is real time - this is a long running process with
|
10
|
+
# continual output, we want it to sync ASAP
|
11
|
+
STDOUT.sync = true
|
12
|
+
|
13
|
+
# Logging - STDOUT only
|
14
|
+
$logger = Logger.new(STDOUT)
|
15
|
+
|
16
|
+
|
17
|
+
# Thor is a toolkit for producing command line applications, see http://whatisthor.com/
|
18
|
+
class CLI < Thor
|
19
|
+
class_option :verbose, :type => :boolean
|
20
|
+
class_option :config, :type => :string
|
21
|
+
|
22
|
+
desc "build", "Build a new archive file"
|
23
|
+
def build
|
24
|
+
|
25
|
+
# Thor seems to force class options to be defined repeatedly? :-/
|
26
|
+
if options[:verbose]
|
27
|
+
$logger.level = Logger::DEBUG
|
28
|
+
else
|
29
|
+
$logger.level = Logger::INFO
|
30
|
+
end
|
31
|
+
|
32
|
+
if options[:config]
|
33
|
+
Pupistry::Config.load(options[:config])
|
34
|
+
else
|
35
|
+
Pupistry::Config.find_and_load
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
begin
|
40
|
+
# Fetch the latest data with r10k
|
41
|
+
artifact = Pupistry::Artifact.new
|
42
|
+
|
43
|
+
artifact.fetch_r10k
|
44
|
+
artifact.build_artifact
|
45
|
+
|
46
|
+
puts "--"
|
47
|
+
puts "Tip: Run pupistry diff to see what changed since the last artifact version"
|
48
|
+
|
49
|
+
rescue Exception => e
|
50
|
+
$logger.fatal "An unexpected error occured when trying to generate the new artifact file"
|
51
|
+
raise e
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
desc "diff", "Show what has changed between now and the current live artifact"
|
59
|
+
def diff
|
60
|
+
|
61
|
+
# Thor seems to force class options to be defined repeatedly? :-/
|
62
|
+
if options[:verbose]
|
63
|
+
$logger.level = Logger::DEBUG
|
64
|
+
else
|
65
|
+
$logger.level = Logger::INFO
|
66
|
+
end
|
67
|
+
|
68
|
+
if options[:config]
|
69
|
+
Pupistry::Config.load(options[:config])
|
70
|
+
else
|
71
|
+
Pupistry::Config.find_and_load
|
72
|
+
end
|
73
|
+
|
74
|
+
# Fetch the latest artifact
|
75
|
+
artifact_upstream = Pupistry::Artifact.new
|
76
|
+
artifact_upstream.checksum = artifact_upstream.fetch_latest
|
77
|
+
|
78
|
+
unless artifact_upstream.checksum
|
79
|
+
$logger.error "There is no upstream artifact to compare to."
|
80
|
+
exit 0
|
81
|
+
end
|
82
|
+
|
83
|
+
artifact_upstream.fetch_artifact
|
84
|
+
|
85
|
+
# Fetch the current artifact
|
86
|
+
artifact_current = Pupistry::Artifact.new
|
87
|
+
artifact_current.checksum = artifact_current.fetch_current
|
88
|
+
|
89
|
+
unless artifact_current.checksum
|
90
|
+
$logger.error "There is no current artifact to compare to, run \"pupistry build\" first to generate one with current changes"
|
91
|
+
exit 0
|
92
|
+
end
|
93
|
+
|
94
|
+
artifact_current.fetch_artifact
|
95
|
+
|
96
|
+
# Unpack the archives
|
97
|
+
artifact_current.unpack
|
98
|
+
artifact_upstream.unpack
|
99
|
+
|
100
|
+
# Diff the contents. This is actually bit of a pain, there's no native way
|
101
|
+
# of diffing an entire directory and a lot of the gems out there that promise
|
102
|
+
# to do diffing a) can't handle dirs and b) generally exec out to native diff
|
103
|
+
# anyway. :-(
|
104
|
+
#
|
105
|
+
# So given this, we might as well go native and just rely on the system
|
106
|
+
# diff command to do the job.
|
107
|
+
|
108
|
+
Dir.chdir("#{$config["general"]["app_cache"]}/artifacts/") do
|
109
|
+
unless system "diff -Nuar unpacked.#{artifact_upstream.checksum} unpacked.#{artifact_current.checksum}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
# Cleanup
|
115
|
+
artifact_current.clean_unpack
|
116
|
+
artifact_upstream.clean_unpack
|
117
|
+
|
118
|
+
puts "--"
|
119
|
+
puts "Tip: Run pupistry push to GPG sign & upload if happy to go live"
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
desc "push", "Sign & Upload a new artifact version"
|
124
|
+
def push
|
125
|
+
|
126
|
+
# Thor seems to force class options to be defined repeatedly? :-/
|
127
|
+
if options[:verbose]
|
128
|
+
$logger.level = Logger::DEBUG
|
129
|
+
else
|
130
|
+
$logger.level = Logger::INFO
|
131
|
+
end
|
132
|
+
|
133
|
+
if options[:config]
|
134
|
+
Pupistry::Config.load(options[:config])
|
135
|
+
else
|
136
|
+
Pupistry::Config.find_and_load
|
137
|
+
end
|
138
|
+
|
139
|
+
# Push the artifact to S3
|
140
|
+
artifact = Pupistry::Artifact.new
|
141
|
+
artifact.push_artifact
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
desc "bootstrap", "Generate a user-data bootstrap script for a node"
|
146
|
+
method_option :template, :type => :string
|
147
|
+
def bootstrap
|
148
|
+
|
149
|
+
# Thor seems to force class options to be defined repeatedly? :-/
|
150
|
+
if options[:verbose]
|
151
|
+
$logger.level = Logger::DEBUG
|
152
|
+
else
|
153
|
+
$logger.level = Logger::INFO
|
154
|
+
end
|
155
|
+
|
156
|
+
if options[:config]
|
157
|
+
Pupistry::Config.load(options[:config])
|
158
|
+
else
|
159
|
+
Pupistry::Config.find_and_load
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
if options[:template]
|
164
|
+
$logger.info "Generating bootstrap template #{options[:template]}"
|
165
|
+
else
|
166
|
+
puts "Listing all avaible templates"
|
167
|
+
Pupistry::Bootstrap.templates_list
|
168
|
+
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
CLI.start(ARGV)
|
176
|
+
|
177
|
+
# vim:shiftwidth=2:tabstop=2:softtabstop=2:expandtab:smartindent
|
data/lib/pupistry.rb
ADDED
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pupistry
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jethro Carr
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk-v1
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: r10k
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Provides security, reliability and consistency to Puppet masterless environments
|
56
|
+
email: jethro.carr@jethrocarr.com
|
57
|
+
executables:
|
58
|
+
- pupistry
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- bin/pupistry
|
63
|
+
- lib/pupistry.rb
|
64
|
+
- README.md
|
65
|
+
homepage: https://github.com/jethrocarr/pupistry
|
66
|
+
licenses:
|
67
|
+
- Apache
|
68
|
+
metadata: {}
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 2.0.14
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: A workflow tool for Puppet Masterless Deployments
|
89
|
+
test_files: []
|