vagrant-pcc 0.0.3
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.
- data/.gitignore +20 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +4 -0
- data/bin/puppet-cert-clean +202 -0
- data/lib/vagrant-pcc.rb +17 -0
- data/lib/vagrant-pcc/action.rb +17 -0
- data/lib/vagrant-pcc/action/cleanup.rb +63 -0
- data/lib/vagrant-pcc/plugin.rb +27 -0
- data/lib/vagrant-pcc/version.rb +7 -0
- data/test +1 -0
- data/vagrant-pcc.gemspec +23 -0
- metadata +98 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Derek Olsen
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Vagrant::Pcc
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'vagrant-pcc'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install vagrant-pcc
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# = puppet-cert-clean -
|
4
|
+
#
|
5
|
+
# == Introduction
|
6
|
+
# The goal of this script is to remove puppet certs when a vagrant
|
7
|
+
# node is being destroyed. As this script is typically being run via
|
8
|
+
# vagrant we will mostly 'exit 0' regardless of what happened instead of
|
9
|
+
# blocking vagrant.
|
10
|
+
#
|
11
|
+
#
|
12
|
+
# To work it requires the puppetmaster have the following in it's
|
13
|
+
# auth.conf. Ideally you would only have this in your dev env.
|
14
|
+
#
|
15
|
+
# path ~ ^/certificate_status/([^/]+)$
|
16
|
+
# auth yes
|
17
|
+
# method find, save, destroy
|
18
|
+
# allow $1
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'optparse'
|
22
|
+
require 'ostruct'
|
23
|
+
require 'fileutils'
|
24
|
+
require 'rubygems'
|
25
|
+
require 'puppet'
|
26
|
+
require 'openssl'
|
27
|
+
require 'net/http'
|
28
|
+
require 'net/https'
|
29
|
+
require 'uri'
|
30
|
+
|
31
|
+
class ParseOptions
|
32
|
+
|
33
|
+
# Make sure we have the puppet settings available before we go
|
34
|
+
# anywhere.
|
35
|
+
begin
|
36
|
+
$puppet_application_mode = Puppet::Util::RunMode[:agent]
|
37
|
+
Puppet[:confdir] = '/etc/puppet'
|
38
|
+
Puppet::Util::RunMode[:agent]
|
39
|
+
Puppet.settings.use :main, :agent
|
40
|
+
Puppet.parse_config
|
41
|
+
rescue Exception => e
|
42
|
+
puts ""
|
43
|
+
puts "An error occurred while loading the puppet settings"
|
44
|
+
puts e
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.parse(args)
|
49
|
+
script_name = File.basename($0)
|
50
|
+
options = OpenStruct.new
|
51
|
+
options.server = Puppet[:ca_server]
|
52
|
+
options.certname = Puppet[:certname]
|
53
|
+
options.ssldir = Puppet[:ssldir]
|
54
|
+
options.localcacert = Puppet[:localcacert]
|
55
|
+
options.hostcert = Puppet[:hostcert]
|
56
|
+
options.hostprivkey = Puppet[:hostprivkey]
|
57
|
+
|
58
|
+
o = OptionParser.new do |o|
|
59
|
+
o.set_summary_indent(' ')
|
60
|
+
o.separator ""
|
61
|
+
o.banner = "\nUsage: #{script_name} [options]\n"
|
62
|
+
o.separator ""
|
63
|
+
|
64
|
+
o.on(
|
65
|
+
"-s", "--server SERVER", "Puppet CA server",
|
66
|
+
"Default: #{options.server}") do |server|
|
67
|
+
options.server = server
|
68
|
+
end
|
69
|
+
o.on(
|
70
|
+
"-c", "--certname CERTNAME", "Certname to clean",
|
71
|
+
"Default: #{options.certname}") do |certname|
|
72
|
+
options.certname = certname
|
73
|
+
end
|
74
|
+
o.on(
|
75
|
+
"-d", "--ssldir SSLDIR", "Where are the certs",
|
76
|
+
"Default: #{options.ssldir}") do |ssldir|
|
77
|
+
options.ssldir = ssldir
|
78
|
+
end
|
79
|
+
o.on(
|
80
|
+
"-t", "--hostcert HOSTCERT", "Path to hosts cert",
|
81
|
+
"Default: #{options.hostcert}") do |hostcert|
|
82
|
+
options.hostcert = hostcert
|
83
|
+
end
|
84
|
+
o.on(
|
85
|
+
"-l", "--localcacert LOCALCACERT", "Path to ca cert",
|
86
|
+
"Default: #{options.localcacert}") do |localcacert|
|
87
|
+
options.localcacert = localcacert
|
88
|
+
end
|
89
|
+
o.on(
|
90
|
+
"-k", "--hostprivkey HOSTPRIVKEY", "Path to hosts private key",
|
91
|
+
"Default: #{options.hostprivkey}") do |hostprivkey|
|
92
|
+
options.hostprivkey = hostprivkey
|
93
|
+
end
|
94
|
+
o.separator ""
|
95
|
+
o.on_tail("-h", "--help", "Show this help message.") do
|
96
|
+
puts o
|
97
|
+
exit
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
begin
|
102
|
+
o.parse!(args)
|
103
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
|
104
|
+
puts e.to_s
|
105
|
+
puts o
|
106
|
+
exit
|
107
|
+
end
|
108
|
+
|
109
|
+
options
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class CertClean
|
114
|
+
attr_accessor :certname, :ssldir, :server, :http, :uri, :status, :localcacert, :hostcert, :hostprivkey, :msg
|
115
|
+
|
116
|
+
def initialize(options = {})
|
117
|
+
options.each_pair {|k,v| instance_variable_set("@#{k}",v) }
|
118
|
+
@state = true
|
119
|
+
end
|
120
|
+
|
121
|
+
def client_files_exist?
|
122
|
+
unless [@hostprivkey, @hostcert, @localcacert].all? {|f| File.exists?(f) }
|
123
|
+
puts "Could not find the nodes cert and key file"
|
124
|
+
exit 0
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def prep_http
|
129
|
+
begin
|
130
|
+
@uri = URI.parse("https://#{@server}:8140/production/certificate_status/#{@certname}")
|
131
|
+
key = File.read(@hostprivkey)
|
132
|
+
cert = File.read(@hostcert)
|
133
|
+
@http = Net::HTTP.new(uri.host,uri.port)
|
134
|
+
@http.use_ssl = true
|
135
|
+
@http.cert = OpenSSL::X509::Certificate.new(cert)
|
136
|
+
@http.key = OpenSSL::PKey::RSA.new(key)
|
137
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
138
|
+
@http.ca_file = File.read(@localcacert)
|
139
|
+
rescue Exception => e
|
140
|
+
@state = false
|
141
|
+
puts "An error occurred while preparing the http connection"
|
142
|
+
puts e
|
143
|
+
exit 0
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def cert_status
|
148
|
+
begin
|
149
|
+
status_request = Net::HTTP::Get.new(uri.request_uri)
|
150
|
+
status_request.add_field("Content-Type", "text/pson")
|
151
|
+
status_request.add_field("Accept", "pson")
|
152
|
+
status_response = @http.request(status_request)
|
153
|
+
# We may not have json available so let's just look at the raw
|
154
|
+
# output.
|
155
|
+
@status = status_response.body.match(/"state":"(signed|revoked)"/) ? $1 : status_response.body
|
156
|
+
rescue Exception => e
|
157
|
+
@state = false
|
158
|
+
puts "An error occurred while trying to status the cert"
|
159
|
+
puts e
|
160
|
+
exit 0
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def revoke_cert
|
165
|
+
begin
|
166
|
+
revoke_request = Net::HTTP::Put.new(uri.request_uri)
|
167
|
+
revoke_request.add_field("Content-Type", "text/pson")
|
168
|
+
revoke_request.add_field("Accept", "pson")
|
169
|
+
revoke_response = @http.request(revoke_request, '{"desired_state":"revoked"}')
|
170
|
+
rescue Exception => e
|
171
|
+
@state = false
|
172
|
+
puts "An error occurred while trying to revoke the cert"
|
173
|
+
puts e
|
174
|
+
exit 0
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def delete_cert
|
179
|
+
begin
|
180
|
+
delete_request = Net::HTTP::Delete.new(uri.request_uri)
|
181
|
+
delete_request.add_field("Accept", "pson")
|
182
|
+
delete_request = @http.request(delete_request)
|
183
|
+
rescue Exception => e
|
184
|
+
@state = false
|
185
|
+
puts "An error occurred while trying to delete the cert"
|
186
|
+
puts e
|
187
|
+
exit 0
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
options = ParseOptions.parse(ARGV)
|
193
|
+
c = CertClean.new(options.marshal_dump)
|
194
|
+
c.client_files_exist?
|
195
|
+
c.prep_http
|
196
|
+
c.cert_status
|
197
|
+
if c.status == 'signed'
|
198
|
+
c.revoke_cert
|
199
|
+
c.delete_cert
|
200
|
+
else
|
201
|
+
puts c.status
|
202
|
+
end
|
data/lib/vagrant-pcc.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
require "vagrant-pcc/plugin"
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module Pcc
|
7
|
+
lib_path = Pathname.new(File.expand_path("../vagrant-pcc", __FILE__))
|
8
|
+
autoload :Action, lib_path.join("action")
|
9
|
+
|
10
|
+
# This returns the path to the source of this plugin.
|
11
|
+
#
|
12
|
+
# @return [Pathname]
|
13
|
+
def self.source_root
|
14
|
+
@source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "vagrant/action/builder"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Pcc
|
5
|
+
module Action
|
6
|
+
action_root = Pathname.new(File.expand_path("../action", __FILE__))
|
7
|
+
autoload :Cleanup, action_root.join("cleanup")
|
8
|
+
|
9
|
+
def self.cleanup
|
10
|
+
Vagrant::Action::Builder.new.tap do |b|
|
11
|
+
b.use Cleanup
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end # Action
|
16
|
+
end # Pcc
|
17
|
+
end # VagrantPlugins
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#require 'FileUtils'
|
2
|
+
module VagrantPlugins
|
3
|
+
module Pcc
|
4
|
+
module Action
|
5
|
+
class Cleanup
|
6
|
+
|
7
|
+
attr_accessor :guestpath
|
8
|
+
|
9
|
+
def initialize(app,env)
|
10
|
+
@app = app
|
11
|
+
end
|
12
|
+
|
13
|
+
def provisioners(name, env)
|
14
|
+
env[:machine].config.vm.provisioners.select do |prov|
|
15
|
+
prov.name == name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def puppet_apply?(env)
|
20
|
+
provisioners(:puppet, env).any?
|
21
|
+
end
|
22
|
+
|
23
|
+
def puppet_agent?(env)
|
24
|
+
provisioners(:puppet_server, env).any?
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup(env)
|
28
|
+
clean_script = 'puppet-cert-clean'
|
29
|
+
script_dir = File.join(Pcc.source_root, 'bin')
|
30
|
+
dst = "#{env[:machine].env.root_path}/puppet-cert-clean"
|
31
|
+
src = "#{script_dir}/#{clean_script}"
|
32
|
+
|
33
|
+
unless File.exists?(dst)
|
34
|
+
FileUtils.cp(src, dst)
|
35
|
+
FileUtils.chmod(0755, dst)
|
36
|
+
end
|
37
|
+
|
38
|
+
env[:machine].config.vm.synced_folders.each do |id, data|
|
39
|
+
@guestpath = data[:guestpath] if data[:hostpath] == "."
|
40
|
+
end
|
41
|
+
|
42
|
+
@guestpath ||= '/vagrant'
|
43
|
+
end
|
44
|
+
|
45
|
+
def call(env)
|
46
|
+
if puppet_apply?(env) or puppet_agent?(env)
|
47
|
+
setup(env)
|
48
|
+
command = "#{@guestpath}/puppet-cert-clean"
|
49
|
+
if env[:machine].state.id != :running
|
50
|
+
env[:ui].info("#{ machine.name} is not running.")
|
51
|
+
end
|
52
|
+
env[:machine].communicate.sudo(command) do | type, data |
|
53
|
+
env[:ui].info(data)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
@app.call(env)
|
58
|
+
end
|
59
|
+
|
60
|
+
end # Cleanup
|
61
|
+
end # Action
|
62
|
+
end # Pcc
|
63
|
+
end # VagrantPlugins
|
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
require "vagrant"
|
3
|
+
rescue LoadError
|
4
|
+
raise "The Vagrant Pcc plugin must be run within Vagrant."
|
5
|
+
end
|
6
|
+
|
7
|
+
# This is a sanity check to make sure no one is attempting to install
|
8
|
+
# this into an early Vagrant version.
|
9
|
+
if Vagrant::VERSION < "1.2.0"
|
10
|
+
raise "The Vagrant Pcc plugin is only compatible with Vagrant 1.2+"
|
11
|
+
end
|
12
|
+
|
13
|
+
module VagrantPlugins
|
14
|
+
module Pcc
|
15
|
+
class Plugin < Vagrant.plugin("2")
|
16
|
+
name "Pcc"
|
17
|
+
description <<-DESC
|
18
|
+
This plugin is intended to clean a guests certificate from a puppet
|
19
|
+
ca server.
|
20
|
+
DESC
|
21
|
+
|
22
|
+
action_hook(:vagrant_pcc_cleanup, :machine_action_destroy) do |hook|
|
23
|
+
hook.before(Vagrant::Action::Builtin::DestroyConfirm, VagrantPlugins::Pcc::Action.cleanup)
|
24
|
+
end
|
25
|
+
end # Plugin
|
26
|
+
end # Pcc
|
27
|
+
end # VagrantPlugins
|
data/vagrant-pcc.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'vagrant-pcc/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "vagrant-pcc"
|
8
|
+
spec.version = VagrantPlugins::Pcc::VERSION
|
9
|
+
spec.authors = ["Derek Olsen"]
|
10
|
+
spec.email = ["derek.olsen@jivesoftware.com"]
|
11
|
+
spec.description = %q{Clean puppet cert}
|
12
|
+
spec.summary = %q{Clean puppet cert}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/) - %w(.vagrant puppet-cert-clean Vagrantfile)
|
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_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vagrant-pcc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Derek Olsen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Clean puppet cert
|
47
|
+
email:
|
48
|
+
- derek.olsen@jivesoftware.com
|
49
|
+
executables:
|
50
|
+
- puppet-cert-clean
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .gitignore
|
55
|
+
- Gemfile
|
56
|
+
- LICENSE.txt
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- bin/puppet-cert-clean
|
60
|
+
- lib/vagrant-pcc.rb
|
61
|
+
- lib/vagrant-pcc/action.rb
|
62
|
+
- lib/vagrant-pcc/action/cleanup.rb
|
63
|
+
- lib/vagrant-pcc/plugin.rb
|
64
|
+
- lib/vagrant-pcc/version.rb
|
65
|
+
- test
|
66
|
+
- vagrant-pcc.gemspec
|
67
|
+
homepage: ''
|
68
|
+
licenses:
|
69
|
+
- MIT
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
hash: 1094222790402685023
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
hash: 1094222790402685023
|
92
|
+
requirements: []
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 1.8.23
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Clean puppet cert
|
98
|
+
test_files: []
|