puppetfactory 0.4.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/LICENSE +13 -0
- data/README.md +0 -0
- data/bin/pfsh +31 -0
- data/bin/puppetfactory +153 -0
- data/lib/puppetfactory.rb +300 -0
- data/lib/puppetfactory/cli.rb +114 -0
- data/lib/puppetfactory/dashboard/rake_tasks.rb +69 -0
- data/lib/puppetfactory/dashboard/serverspec_helper.rb +84 -0
- data/lib/puppetfactory/dashboard/spec_helper.rb +26 -0
- data/lib/puppetfactory/helpers.rb +37 -0
- data/lib/puppetfactory/monkeypatches.rb +30 -0
- data/lib/puppetfactory/plugins.rb +11 -0
- data/lib/puppetfactory/plugins/certificates.rb +28 -0
- data/lib/puppetfactory/plugins/classification.rb +75 -0
- data/lib/puppetfactory/plugins/code_manager.rb +156 -0
- data/lib/puppetfactory/plugins/console_user.rb +62 -0
- data/lib/puppetfactory/plugins/dashboard.rb +128 -0
- data/lib/puppetfactory/plugins/docker.rb +193 -0
- data/lib/puppetfactory/plugins/example.rb +88 -0
- data/lib/puppetfactory/plugins/github.rb +102 -0
- data/lib/puppetfactory/plugins/gitlab.rb +62 -0
- data/lib/puppetfactory/plugins/hooks.rb +46 -0
- data/lib/puppetfactory/plugins/login_shell.rb +10 -0
- data/lib/puppetfactory/plugins/logs.rb +34 -0
- data/lib/puppetfactory/plugins/r10k.rb +112 -0
- data/lib/puppetfactory/plugins/shell_user.rb +69 -0
- data/lib/puppetfactory/plugins/user_environment.rb +77 -0
- data/public/dashboard.js +100 -0
- data/public/font-awesome/css/font-awesome.css +2199 -0
- data/public/font-awesome/css/font-awesome.min.css +4 -0
- data/public/font-awesome/fonts/FontAwesome.otf +0 -0
- data/public/font-awesome/fonts/fontawesome-webfont.eot +0 -0
- data/public/font-awesome/fonts/fontawesome-webfont.svg +685 -0
- data/public/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
- data/public/font-awesome/fonts/fontawesome-webfont.woff +0 -0
- data/public/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
- data/public/gitviz/LICENSE.md +20 -0
- data/public/gitviz/README.md +13 -0
- data/public/gitviz/css/explaingit.css +227 -0
- data/public/gitviz/css/vendor/1140.css +130 -0
- data/public/gitviz/images/forkme_right_red_aa0000.png +0 -0
- data/public/gitviz/images/grippy-close.png +0 -0
- data/public/gitviz/images/grippy.png +0 -0
- data/public/gitviz/images/prompt.gif +0 -0
- data/public/gitviz/index.html +734 -0
- data/public/gitviz/js/controlbox.js +459 -0
- data/public/gitviz/js/explaingit.js +74 -0
- data/public/gitviz/js/historyview.js +979 -0
- data/public/gitviz/js/main.js +56 -0
- data/public/gitviz/js/vendor/d3.min.js +4 -0
- data/public/gitviz/js/vendor/jquery-latest.min.js +6 -0
- data/public/gitviz/js/vendor/normalize.css +396 -0
- data/public/gitviz/js/vendor/require.min.js +35 -0
- data/public/gitviz/memtest.html +44 -0
- data/public/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/public/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/public/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/public/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/public/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/public/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/public/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/public/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/public/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/public/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/public/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/public/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/public/images/ui-icons_222222_256x240.png +0 -0
- data/public/images/ui-icons_228ef1_256x240.png +0 -0
- data/public/images/ui-icons_454545_256x240.png +0 -0
- data/public/images/ui-icons_ef8c08_256x240.png +0 -0
- data/public/images/ui-icons_ffd27a_256x240.png +0 -0
- data/public/images/ui-icons_ffffff_256x240.png +0 -0
- data/public/jquery-1.11.1.min.js +4 -0
- data/public/jquery-ui.css +464 -0
- data/public/jquery-ui.min.css +7 -0
- data/public/jquery-ui.min.js +13 -0
- data/public/jquery-ui.structure.min.css +5 -0
- data/public/jquery-ui.theme.min.css +5 -0
- data/public/jquery.activity-indicator-1.0.0.min.js +10 -0
- data/public/jquery.js +9789 -0
- data/public/loginscripts.js +18 -0
- data/public/scripts.js +36 -0
- data/public/style.css +193 -0
- data/public/usermanagement.js +133 -0
- data/templates/init_scripts.erb +10 -0
- data/templates/puppet.conf.erb +10 -0
- data/templates/site.pp.erb +50 -0
- data/views/dashboard.erb +62 -0
- data/views/home.erb +43 -0
- data/views/index.erb +29 -0
- data/views/logs.erb +26 -0
- data/views/shell.erb +35 -0
- data/views/users.erb +69 -0
- metadata +256 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
require 'puppetfactory'
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'httparty'
|
|
5
|
+
|
|
6
|
+
class Puppetfactory
|
|
7
|
+
class Cli
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
if options[:server]
|
|
10
|
+
@server = options[:server]
|
|
11
|
+
else
|
|
12
|
+
@server = 'localhost'
|
|
13
|
+
end
|
|
14
|
+
@server = "http://#{@server}:#{options[:port]}" unless @server.start_with? 'http'
|
|
15
|
+
@master = options[:master]
|
|
16
|
+
@debug = options[:debug]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def list()
|
|
20
|
+
begin
|
|
21
|
+
puts ' Username Sandbox URL Certname Container | Node Group'
|
|
22
|
+
response = HTTParty.get("#{@server}/api/users")
|
|
23
|
+
raise "PuppetFactory service not responding: #{@server}" unless response.code == 200
|
|
24
|
+
|
|
25
|
+
JSON.parse(response.body).each do |user, params|
|
|
26
|
+
container = params['container_status']['Dead'] ? 'X' : '+' rescue '?'
|
|
27
|
+
nodegroup = params['node_group_url'].nil? ? 'X' : '+'
|
|
28
|
+
printf("%-14s https://%s%10s %-25s %1s %1s\n", user, @master, params['url'], params['certname'], container, nodegroup)
|
|
29
|
+
end
|
|
30
|
+
rescue => e
|
|
31
|
+
puts "API error listing users: #{e.message}"
|
|
32
|
+
puts e.backtrace if @debug
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def create(user, password)
|
|
37
|
+
begin
|
|
38
|
+
params = {
|
|
39
|
+
body: {
|
|
40
|
+
username: user,
|
|
41
|
+
password: password
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
response = HTTParty.post("#{@server}/api/users", params)
|
|
45
|
+
raise "PuppetFactory error: #{response.body}" unless response.code == 200
|
|
46
|
+
|
|
47
|
+
data = JSON.parse(response.body)
|
|
48
|
+
raise data['message'] unless data['status'] == 'success'
|
|
49
|
+
|
|
50
|
+
puts "User #{user} created."
|
|
51
|
+
rescue => e
|
|
52
|
+
puts "API error creating user #{user}: #{e.message}"
|
|
53
|
+
puts e.backtrace if @debug
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def delete(user)
|
|
58
|
+
begin
|
|
59
|
+
response = HTTParty.delete("#{@server}/api/users/#{user}")
|
|
60
|
+
raise "Puppetfactory error: #{response.body}" unless response.code == 200
|
|
61
|
+
|
|
62
|
+
data = JSON.parse(response.body)
|
|
63
|
+
raise data['message'] unless data['status'] == 'success'
|
|
64
|
+
|
|
65
|
+
puts "User #{user} deleted."
|
|
66
|
+
rescue => e
|
|
67
|
+
puts "API error deleting user #{user}: #{e.message}"
|
|
68
|
+
puts e.backtrace if @debug
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def repair(user)
|
|
73
|
+
begin
|
|
74
|
+
response = HTTParty.put("#{@server}/api/users/#{user}",
|
|
75
|
+
{ body: {
|
|
76
|
+
username: user,
|
|
77
|
+
action: "repair"}
|
|
78
|
+
})
|
|
79
|
+
raise "Puppetfactory error: #{response.body}" unless response.code == 200
|
|
80
|
+
|
|
81
|
+
data = JSON.parse(response.body)
|
|
82
|
+
raise data['message'] unless data['status'] == 'success'
|
|
83
|
+
|
|
84
|
+
puts "User #{user} repaired."
|
|
85
|
+
rescue => e
|
|
86
|
+
puts "API error repair user #{user}: #{e.message}"
|
|
87
|
+
puts e.backtrace if @debug
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
def redeploy(user)
|
|
91
|
+
begin
|
|
92
|
+
response = HTTParty.put("#{@server}/api/users/#{user}",
|
|
93
|
+
{ body: {
|
|
94
|
+
username: user,
|
|
95
|
+
action: "redeploy"}
|
|
96
|
+
})
|
|
97
|
+
raise "Puppetfactory error: #{response.body}" unless response.code == 200
|
|
98
|
+
|
|
99
|
+
data = JSON.parse(response.body)
|
|
100
|
+
raise data['message'] unless data['status'] == 'success'
|
|
101
|
+
|
|
102
|
+
puts "User #{user} repaired."
|
|
103
|
+
rescue => e
|
|
104
|
+
puts "API error redeploying environment #{user}: #{e.message}"
|
|
105
|
+
puts e.backtrace if @debug
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test()
|
|
110
|
+
require 'pry'
|
|
111
|
+
binding.pry
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'rake'
|
|
3
|
+
require 'rspec/core/rake_task'
|
|
4
|
+
|
|
5
|
+
task :spec => 'spec:all_agents'
|
|
6
|
+
task :default => :spec
|
|
7
|
+
|
|
8
|
+
desc "List all available tests"
|
|
9
|
+
task :list do
|
|
10
|
+
Dir.glob('spec/*').sort.each do |dir|
|
|
11
|
+
puts File.basename(dir, '_spec.rb')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
desc "Run each test and summarize their output"
|
|
16
|
+
task :generate => [:spec] do
|
|
17
|
+
output = {'timestamp' => Time.now}
|
|
18
|
+
Dir.glob("output/json/*.json") do |file|
|
|
19
|
+
name = File.basename(file, '.json')
|
|
20
|
+
data = JSON.parse(File.read(file)) rescue {}
|
|
21
|
+
output[name] ||= {}
|
|
22
|
+
output[name]['summary'] = data['summary']
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Dir.glob("output/json/*/*.json") do |file|
|
|
26
|
+
current, name = file.chomp('.json').split('/').last(2)
|
|
27
|
+
data = JSON.parse(File.read(file)) rescue {}
|
|
28
|
+
output[name] ||= {}
|
|
29
|
+
output[name][current] = data['summary']
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
File.write('output/summary.json', output.to_json)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
namespace :spec do
|
|
36
|
+
targets = []
|
|
37
|
+
Dir.glob('/etc/puppetlabs/code/environments/*').each do |dir|
|
|
38
|
+
next unless File.directory?(dir)
|
|
39
|
+
next unless dir.end_with? '_production'
|
|
40
|
+
target = File.basename(dir.sub('_production', ''))
|
|
41
|
+
targets << target
|
|
42
|
+
end
|
|
43
|
+
task :all_agents => targets
|
|
44
|
+
|
|
45
|
+
if ENV.include? 'current_test'
|
|
46
|
+
test = ENV['current_test']
|
|
47
|
+
html = "output/html/#{test}"
|
|
48
|
+
json = "output/json/#{test}"
|
|
49
|
+
pattern = "spec/#{test}_spec.rb"
|
|
50
|
+
else
|
|
51
|
+
html = "output/html"
|
|
52
|
+
json = "output/json"
|
|
53
|
+
pattern = "spec/*_spec.rb"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
FileUtils.mkdir_p html
|
|
57
|
+
FileUtils.mkdir_p json
|
|
58
|
+
|
|
59
|
+
targets.each do |target|
|
|
60
|
+
desc "Run Puppetfactory tests for #{target}"
|
|
61
|
+
RSpec::Core::RakeTask.new(target.to_sym) do |t|
|
|
62
|
+
ENV['TARGET_HOST'] = target
|
|
63
|
+
t.verbose = false
|
|
64
|
+
t.fail_on_error = false
|
|
65
|
+
t.rspec_opts = "--format html --out #{html}/#{target}.html --format json --out #{json}/#{target}.json"
|
|
66
|
+
t.pattern = pattern
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'serverspec'
|
|
2
|
+
require "docker"
|
|
3
|
+
|
|
4
|
+
set :backend, :docker
|
|
5
|
+
username = ENV['TARGET_HOST']
|
|
6
|
+
|
|
7
|
+
set :docker_container, Docker::Container.get(username).id
|
|
8
|
+
|
|
9
|
+
# Serverspec types and matchers below. Until we decide to gemify them :)
|
|
10
|
+
|
|
11
|
+
# This defines the method used to build the test case
|
|
12
|
+
def puppet
|
|
13
|
+
Serverspec::Type::Puppet.new()
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module Serverspec::Type
|
|
17
|
+
class Puppet < Base
|
|
18
|
+
|
|
19
|
+
def initialize
|
|
20
|
+
super
|
|
21
|
+
return unless @settings.nil?
|
|
22
|
+
|
|
23
|
+
@settings = {}
|
|
24
|
+
data = @runner.run_command('puppet agent --configprint all').stdout
|
|
25
|
+
data.split("\n").each do |line|
|
|
26
|
+
key, value = line.split(' = ')
|
|
27
|
+
@settings[key.to_sym] = value
|
|
28
|
+
|
|
29
|
+
self.class.send(:define_method, key) { value }
|
|
30
|
+
#define_method(key) { value }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_s
|
|
35
|
+
'Puppet managed attributes'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def enabled?
|
|
39
|
+
not disabled?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def disabled?
|
|
43
|
+
@runner.check_file_is_file(@settings[:agent_disabled_lockfile])
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def has_signed_cert?
|
|
47
|
+
@runner.check_file_is_file(@settings[:hostcert])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def has_run_puppet?
|
|
51
|
+
@runner.check_file_is_file(@settings[:lastrunreport])
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def classified_with?(klass)
|
|
55
|
+
#@runner.check_file_contains(@settings[:classfile], /^klass$/)
|
|
56
|
+
@classfile ||= @runner.get_file_content(@settings[:classfile]).stdout
|
|
57
|
+
@classfile =~ /^#{klass}$/
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def has_resource?(resource)
|
|
61
|
+
#@runner.check_file_contains(@settings[:resourcefile], resource)
|
|
62
|
+
@resourcefile ||= @runner.get_file_content(@settings[:resourcefile]).stdout
|
|
63
|
+
|
|
64
|
+
case resource
|
|
65
|
+
when String
|
|
66
|
+
@resourcefile.include? resource
|
|
67
|
+
when Regexp
|
|
68
|
+
@resourcefile =~ /^#{resource}$/
|
|
69
|
+
else
|
|
70
|
+
false
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
RSpec::Matchers.define :manage_resource do |resource|
|
|
77
|
+
match do |subject|
|
|
78
|
+
if subject.class.name == 'Serverspec::Type::Puppet'
|
|
79
|
+
subject.has_resource?(resource)
|
|
80
|
+
else
|
|
81
|
+
raise "The 'manage_resource' matcher does not support #{subject.class.name}."
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'rspec-puppet'
|
|
2
|
+
# we can't use psh, because it declares things that conflict with serverspec
|
|
3
|
+
|
|
4
|
+
username = ENV['TARGET_HOST']
|
|
5
|
+
environmentpath = "/etc/puppetlabs/code/environments"
|
|
6
|
+
|
|
7
|
+
if File.directory? "#{environmentpath}/#{username}_production"
|
|
8
|
+
environment = "#{username}_production"
|
|
9
|
+
else
|
|
10
|
+
environment = username
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
RSpec.configure do |c|
|
|
14
|
+
c.environmentpath = environmentpath
|
|
15
|
+
c.module_path = "#{environmentpath}/#{environment}/site"
|
|
16
|
+
c.manifest = "#{environmentpath}/#{environment}/manifests"
|
|
17
|
+
|
|
18
|
+
# Adds to the built in defaults from rspec-puppet
|
|
19
|
+
c.default_facts = {
|
|
20
|
+
:ipaddress => '127.0.0.1',
|
|
21
|
+
:kernel => 'Linux',
|
|
22
|
+
:operatingsystem => 'CentOS',
|
|
23
|
+
:operatingsystemmajrelease => '7',
|
|
24
|
+
:osfamily => 'RedHat',
|
|
25
|
+
}
|
|
26
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'puppetfactory'
|
|
2
|
+
|
|
3
|
+
class Puppetfactory::Helpers
|
|
4
|
+
|
|
5
|
+
def self.configure(options)
|
|
6
|
+
@@options = options
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.environment_name(username)
|
|
10
|
+
case @@options[:repomodel]
|
|
11
|
+
when :peruser
|
|
12
|
+
"#{username}_production"
|
|
13
|
+
|
|
14
|
+
when :single
|
|
15
|
+
username
|
|
16
|
+
|
|
17
|
+
else
|
|
18
|
+
raise "Invalid setting for repomodel (#{repomodel})"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.approximate_time_difference(timestamp)
|
|
23
|
+
return 'never' if timestamp.nil?
|
|
24
|
+
|
|
25
|
+
start = timestamp.class == String ? Time.parse(timestamp) : timestamp
|
|
26
|
+
delta = (Time.now - start)
|
|
27
|
+
|
|
28
|
+
if delta > 60
|
|
29
|
+
# This grossity is rounding to the nearest whole minute
|
|
30
|
+
mins = ((delta / 600).round(1)*10).to_i
|
|
31
|
+
"about #{mins} minutes ago"
|
|
32
|
+
else
|
|
33
|
+
"#{delta.to_i} seconds ago"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class String
|
|
2
|
+
if not String.method_defined? :snake_case
|
|
3
|
+
def snake_case!
|
|
4
|
+
gsub!(/(.)([A-Z])/,'\1_\2')
|
|
5
|
+
downcase!
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def snake_case
|
|
9
|
+
dup.tap { |s| s.snake_case! }
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if not String.method_defined? :trim
|
|
14
|
+
def trim(size)
|
|
15
|
+
if self.size > size
|
|
16
|
+
"#{self[0...(size - 1)]}…"
|
|
17
|
+
else
|
|
18
|
+
self
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class Symbol
|
|
25
|
+
if not Symbol.method_defined? :snake_case
|
|
26
|
+
def snake_case
|
|
27
|
+
to_s.snake_case.to_sym
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'puppetfactory'
|
|
2
|
+
class Puppetfactory::Plugins::Certificates < Puppetfactory::Plugins
|
|
3
|
+
|
|
4
|
+
def initialize(options)
|
|
5
|
+
super(options)
|
|
6
|
+
|
|
7
|
+
@puppet = options[:puppet]
|
|
8
|
+
@suffix = options[:usersuffix]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def delete(username)
|
|
12
|
+
certname = "#{username}.#{@suffix}"
|
|
13
|
+
|
|
14
|
+
output, status = Open3.capture2e('puppet', 'cert', 'clean', certname)
|
|
15
|
+
unless status.success?
|
|
16
|
+
$logger.warn "Error cleaning certificate #{certname}: #{output}"
|
|
17
|
+
return false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
$logger.info "Certificate #{certname} removed"
|
|
21
|
+
true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def repair(username)
|
|
25
|
+
delete(username)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'puppetfactory'
|
|
3
|
+
require 'puppetclassify'
|
|
4
|
+
|
|
5
|
+
class Puppetfactory::Plugins::Classification < Puppetfactory::Plugins
|
|
6
|
+
|
|
7
|
+
def initialize(options)
|
|
8
|
+
super(options)
|
|
9
|
+
|
|
10
|
+
@weight = 25
|
|
11
|
+
@puppet = options[:puppet]
|
|
12
|
+
@suffix = options[:usersuffix]
|
|
13
|
+
@master = options[:master]
|
|
14
|
+
classifier = options[:classifier] || "http://#{@master}:4433/classifier-api"
|
|
15
|
+
|
|
16
|
+
auth_info = options[:auth_info] || {}
|
|
17
|
+
auth_info['ca_certificate_path'] ||= "#{options[:confdir]}/ssl/ca/ca_crt.pem"
|
|
18
|
+
auth_info['certificate_path'] ||= "#{options[:confdir]}/ssl/certs/#{options[:master]}.pem"
|
|
19
|
+
auth_info['private_key_path'] ||= "#{options[:confdir]}/ssl/private_keys/#{options[:master]}.pem"
|
|
20
|
+
|
|
21
|
+
@puppetclassify = PuppetClassify.new(classifier, auth_info)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def create(username, password)
|
|
25
|
+
environment = Puppetfactory::Helpers.environment_name(username)
|
|
26
|
+
certname = "#{username}.#{@suffix}"
|
|
27
|
+
|
|
28
|
+
group_hash = {
|
|
29
|
+
'name' => certname,
|
|
30
|
+
'environment' => environment,
|
|
31
|
+
'environment_trumps' => true,
|
|
32
|
+
'parent' => '00000000-0000-4000-8000-000000000000',
|
|
33
|
+
'classes' => {},
|
|
34
|
+
'rule' => ['or', ['=', 'name', certname]]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
begin
|
|
38
|
+
@puppetclassify.groups.create_group(group_hash)
|
|
39
|
+
rescue => e
|
|
40
|
+
$logger.error "Could not create node group #{certname}: #{e.message}"
|
|
41
|
+
return false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
$logger.info "Created node group #{certname} assigned to environment #{environment}"
|
|
45
|
+
true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def delete(username)
|
|
49
|
+
certname = "#{username}.#{@suffix}"
|
|
50
|
+
|
|
51
|
+
begin
|
|
52
|
+
group_id = @puppetclassify.groups.get_group_id(certname)
|
|
53
|
+
@puppetclassify.groups.delete_group(group_id)
|
|
54
|
+
rescue => e
|
|
55
|
+
$logger.warn "Error removing node group #{certname}: #{e.message}"
|
|
56
|
+
return false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
$logger.info "Node group #{certname} removed"
|
|
60
|
+
true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def userinfo(username, extended = false)
|
|
64
|
+
return unless extended
|
|
65
|
+
|
|
66
|
+
ngid = @puppetclassify.groups.get_group_id("#{username}.#{@suffix}")
|
|
67
|
+
|
|
68
|
+
{
|
|
69
|
+
:username => username,
|
|
70
|
+
:node_group_id => ngid,
|
|
71
|
+
:node_group_url => "https://#{@master}/#/node_groups/groups/#{ngid}",
|
|
72
|
+
}
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|