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,88 @@
|
|
|
1
|
+
require 'puppetfactory'
|
|
2
|
+
|
|
3
|
+
# inherit from Puppetfactory::Plugins
|
|
4
|
+
class Puppetfactory::Plugins::Example < Puppetfactory::Plugins
|
|
5
|
+
attr_reader :weight
|
|
6
|
+
|
|
7
|
+
def initialize(options)
|
|
8
|
+
super(options) # call the superclass to initialize it
|
|
9
|
+
|
|
10
|
+
@weight = 1
|
|
11
|
+
@example = options[:example] || '/tmp/example'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# include one or more of the following methods. Any method you implement
|
|
15
|
+
# will be called when the corresponding task is invoked.
|
|
16
|
+
|
|
17
|
+
def create(username, password)
|
|
18
|
+
$logger.info "User #{username} created."
|
|
19
|
+
|
|
20
|
+
# Log an error with $logger.error
|
|
21
|
+
# fail user creation with a fatal error by raising an exception
|
|
22
|
+
|
|
23
|
+
# return true if our action succeeded
|
|
24
|
+
true
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def delete(username)
|
|
28
|
+
$logger.info "User #{username} deleted."
|
|
29
|
+
|
|
30
|
+
# return true if our action succeeded
|
|
31
|
+
true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def userinfo(username, extended = false)
|
|
35
|
+
# we can bail if we don't want to add to the basic user object.
|
|
36
|
+
# for example, if these are heavy operations.
|
|
37
|
+
return unless extended
|
|
38
|
+
|
|
39
|
+
# return a hash with the :username key
|
|
40
|
+
{
|
|
41
|
+
:username => username,
|
|
42
|
+
:example => username.upcase,
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def deploy(username)
|
|
47
|
+
environment = Puppetfactory::Helpers.environment_name(username)
|
|
48
|
+
$logger.info "Deployed environment #{environment} for #{username}"
|
|
49
|
+
|
|
50
|
+
# return true if our action succeeded
|
|
51
|
+
true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def redeploy(username)
|
|
55
|
+
begin
|
|
56
|
+
if username == 'production'
|
|
57
|
+
raise "Can't redeploy production environment"
|
|
58
|
+
end
|
|
59
|
+
delete(username)
|
|
60
|
+
deploy(username)
|
|
61
|
+
|
|
62
|
+
rescue => e
|
|
63
|
+
raise "Error redeploying environment #{username}: #{e.message}"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# return true if our action succeeded
|
|
67
|
+
true
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# used by container plugins to rebuild them
|
|
71
|
+
def repair(username)
|
|
72
|
+
$logger.info "Container #{username} repaired"
|
|
73
|
+
true
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# hook called when users log in. Only one can be active at any time.
|
|
77
|
+
def login
|
|
78
|
+
$logger.info 'Logging in with the default system shell'
|
|
79
|
+
exec('bash --login')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# returns an array of all user accounts. Only one can be active at any time.
|
|
83
|
+
def users
|
|
84
|
+
usernames = Dir.glob('/home/*').map { |path| File.basename path }
|
|
85
|
+
usernames.reject { |username| ['centos', 'training', 'showoff'].include? username }
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require 'octokit'
|
|
2
|
+
require 'puppetfactory'
|
|
3
|
+
|
|
4
|
+
class Puppetfactory::Plugins::Github < Puppetfactory::Plugins
|
|
5
|
+
|
|
6
|
+
def initialize(options)
|
|
7
|
+
super(options)
|
|
8
|
+
|
|
9
|
+
@gitserver = options[:gitserver]
|
|
10
|
+
@gituser = options[:gituser]
|
|
11
|
+
@controlrepo = options[:controlrepo]
|
|
12
|
+
@repomodel = options[:repomodel]
|
|
13
|
+
@githubtoken = options[:githubtoken]
|
|
14
|
+
|
|
15
|
+
# chomp so we can support repo names with or without the .git
|
|
16
|
+
@controlrepo.chomp!('.git')
|
|
17
|
+
|
|
18
|
+
if @githubtoken
|
|
19
|
+
@client = Octokit::Client.new(:access_token => @githubtoken)
|
|
20
|
+
@client.user.login
|
|
21
|
+
else
|
|
22
|
+
@client = Octokit::Client.new()
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def create(username, password)
|
|
27
|
+
# can only do anything on our own repo, and only if we're authorized!
|
|
28
|
+
return true unless @githubtoken and @repomodel == :single
|
|
29
|
+
|
|
30
|
+
begin
|
|
31
|
+
# can only do anything on our own repo!
|
|
32
|
+
repo = "#{@gituser}/#{@controlrepo}"
|
|
33
|
+
sha = @client.branches(repo).select { |branch| branch[:name] == 'production' }.first[:commit][:sha]
|
|
34
|
+
@client.create_ref(repo, "heads/#{username}", sha)
|
|
35
|
+
$logger.info "Created Github user branch for #{username}"
|
|
36
|
+
|
|
37
|
+
@client.add_collaborator(repo, username)
|
|
38
|
+
$logger.info "Added #{username} as a collaborator to #{repo}."
|
|
39
|
+
|
|
40
|
+
rescue => e
|
|
41
|
+
$logger.error "Error creating Github user branch for #{username}"
|
|
42
|
+
$logger.error e.message
|
|
43
|
+
return false
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def delete(username)
|
|
50
|
+
# can only do anything on our own repo, and only if we're authorized!
|
|
51
|
+
return true unless @githubtoken and @repomodel == :single
|
|
52
|
+
|
|
53
|
+
begin
|
|
54
|
+
@client.delete_branch("#{@gituser}/#{@controlrepo}", username)
|
|
55
|
+
$logger.info "Deleted Github user branch for #{username}"
|
|
56
|
+
|
|
57
|
+
@client.remove_collaborator(repo, username)
|
|
58
|
+
$logger.info "Removed #{username} as a collaborator on #{repo}."
|
|
59
|
+
|
|
60
|
+
rescue => e
|
|
61
|
+
$logger.error "Error deleting Github user branch for #{username}"
|
|
62
|
+
$logger.error e.message
|
|
63
|
+
return false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
true
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def userinfo(username, extended = false)
|
|
70
|
+
if @repomodel == :single
|
|
71
|
+
repo = "#{@gituser}/#{@controlrepo}"
|
|
72
|
+
url = "#{@gitserver}/#{@gituser}/#{@controlrepo}/tree/#{username}"
|
|
73
|
+
else
|
|
74
|
+
repo = "#{@username}/#{@controlrepo}"
|
|
75
|
+
url = "#{@gitserver}/#{username}/#{@controlrepo}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
userinfo = {
|
|
79
|
+
:username => username,
|
|
80
|
+
:controlrepo => url,
|
|
81
|
+
}
|
|
82
|
+
userinfo[:latestcommit] = latest_commit(repo, username) if extended
|
|
83
|
+
userinfo
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
def latest_commit(repo, username)
|
|
88
|
+
begin
|
|
89
|
+
commit = @client.commits(repo, :author => username).first
|
|
90
|
+
return if commit.nil?
|
|
91
|
+
|
|
92
|
+
{
|
|
93
|
+
:url => commit[:html_url],
|
|
94
|
+
:message => commit[:commit][:message].trim(62),
|
|
95
|
+
:time => Puppetfactory::Helpers.approximate_time_difference(commit[:commit][:author][:date]),
|
|
96
|
+
}
|
|
97
|
+
rescue => e
|
|
98
|
+
$logger.error "Cannot get commits for #{repo}."
|
|
99
|
+
$logger.error e.message
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'puppetfactory'
|
|
3
|
+
|
|
4
|
+
class Puppetfactory::Plugins::Gitlab < Puppetfactory::Plugins
|
|
5
|
+
|
|
6
|
+
def initialize(options)
|
|
7
|
+
super(options)
|
|
8
|
+
|
|
9
|
+
@suffix = options[:usersuffix]
|
|
10
|
+
|
|
11
|
+
begin
|
|
12
|
+
# Use default gitlab root password to get session token
|
|
13
|
+
login = {:login => 'root', :password => '5iveL!fe'}
|
|
14
|
+
resp = JSON.parse(RestClient.post('http://localhost:8888/api/v3/session', login))
|
|
15
|
+
@token = resp['private_token']
|
|
16
|
+
rescue => e
|
|
17
|
+
raise "GitLab authentication error! (#{e.message})"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create(username, password)
|
|
22
|
+
begin
|
|
23
|
+
if password.length < 8
|
|
24
|
+
raise "Password must be at least 8 characters"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
RestClient.post('http://localhost:8888/api/v3/users',
|
|
28
|
+
{
|
|
29
|
+
:email => "#{username}.#{@suffix}",
|
|
30
|
+
:password => password,
|
|
31
|
+
:username => username,
|
|
32
|
+
:name => username,
|
|
33
|
+
:confirm => false,
|
|
34
|
+
:private_token => @token # TODO: this invocation does not look like the invocation below?
|
|
35
|
+
})
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
$logger.info "Created GitLab user #{username}."
|
|
39
|
+
rescue => e
|
|
40
|
+
$logger.error "Error creating GitLab user #{username}: #{e.message}"
|
|
41
|
+
return false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def delete(username)
|
|
48
|
+
begin
|
|
49
|
+
users = JSON.parse(RestClient.get('http://localhost:8888/api/v3/users', {"PRIVATE-TOKEN" => @token}))
|
|
50
|
+
userid = users.select { |record| record['username'] == username }['id']
|
|
51
|
+
RestClient.delete("http://localhost:8888/api/v3/users/#{userid}" , {"PRIVATE-TOKEN" => @token})
|
|
52
|
+
|
|
53
|
+
$logger.info "Removed GitLab user #{username}."
|
|
54
|
+
rescue => e
|
|
55
|
+
$logger.error "Error removing GitLab user #{username}: #{e.message}"
|
|
56
|
+
return false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
true
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'puppetfactory'
|
|
3
|
+
|
|
4
|
+
class Puppetfactory::Plugins::Hooks < Puppetfactory::Plugins
|
|
5
|
+
attr_reader :weight
|
|
6
|
+
|
|
7
|
+
def initialize(options)
|
|
8
|
+
super(options)
|
|
9
|
+
|
|
10
|
+
@weight = 1
|
|
11
|
+
@path = options[:hooks_path] || '/etc/puppetfactory/hooks'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create(username)
|
|
15
|
+
call_hooks(:create, username)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def delete(username)
|
|
19
|
+
call_hooks(:delete, username)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
def call_hooks(hook_type, username)
|
|
24
|
+
success = true
|
|
25
|
+
# the .to_s allows us to accept strings or symbols
|
|
26
|
+
Dir.glob("#{HOOKS_PATH}/#{hook_type.to_s}/*") do |hook|
|
|
27
|
+
next unless File.file?(hook)
|
|
28
|
+
next unless File.executable?(hook)
|
|
29
|
+
|
|
30
|
+
begin
|
|
31
|
+
output, status = Open3.capture2e(hook, username)
|
|
32
|
+
raise "Execution error: #{output}" unless status.success?
|
|
33
|
+
$logger.info output
|
|
34
|
+
|
|
35
|
+
rescue => e
|
|
36
|
+
$logger.error "Error running hook: #{hook}"
|
|
37
|
+
$logger.error e.message
|
|
38
|
+
success = false
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# only true if all hooks succeeded.
|
|
43
|
+
success
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'puppetfactory'
|
|
2
|
+
|
|
3
|
+
class Puppetfactory::Plugins::Logs < Puppetfactory::Plugins
|
|
4
|
+
|
|
5
|
+
def initialize(options)
|
|
6
|
+
super(options)
|
|
7
|
+
return unless options[:puppetfactory]
|
|
8
|
+
|
|
9
|
+
@logfile = options[:logfile]
|
|
10
|
+
server = options[:puppetfactory]
|
|
11
|
+
|
|
12
|
+
# Add a web route to the puppetfactory server. Must happen in the initializer
|
|
13
|
+
server.get '/logs' do
|
|
14
|
+
protected!
|
|
15
|
+
erb :logs
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
server.get '/logs/data' do
|
|
19
|
+
protected!
|
|
20
|
+
plugin(:Logs, :data)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def tabs(privileged = false)
|
|
25
|
+
return unless privileged # only show this tab to admin users
|
|
26
|
+
|
|
27
|
+
# url path => display title
|
|
28
|
+
{ 'logs' => 'Logs' }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def data
|
|
32
|
+
File.read(@logfile) rescue "Cannot read logfile #{@logfile}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
require 'puppetfactory'
|
|
2
|
+
|
|
3
|
+
class Puppetfactory::Plugins::R10k < Puppetfactory::Plugins
|
|
4
|
+
|
|
5
|
+
def initialize(options)
|
|
6
|
+
super(options)
|
|
7
|
+
|
|
8
|
+
@gitserver = options[:gitserver]
|
|
9
|
+
@repomodel = options[:repomodel]
|
|
10
|
+
@controlrepo = options[:controlrepo]
|
|
11
|
+
@environments = options[:environments]
|
|
12
|
+
@r10k_config = '/etc/puppetlabs/r10k/r10k.yaml'
|
|
13
|
+
@pattern = "#{@gitserver}/%s/#{@controlrepo}"
|
|
14
|
+
|
|
15
|
+
# the rest of this method is for the big boys only
|
|
16
|
+
return unless Process.euid == 0
|
|
17
|
+
|
|
18
|
+
# in case this is the first run and it doesn't exist yet
|
|
19
|
+
unless File.exist? @r10k_config
|
|
20
|
+
File.open(@r10k_config, 'w') { |f| f.write({'sources' => {}}.to_yaml) }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def create(username, password)
|
|
25
|
+
begin
|
|
26
|
+
environment = "#{@environments}/#{Puppetfactory::Helpers.environment_name(username)}"
|
|
27
|
+
FileUtils.mkdir_p environment
|
|
28
|
+
FileUtils.chown_R(username, 'pe-puppet', environment)
|
|
29
|
+
FileUtils.chmod(0750, environment)
|
|
30
|
+
|
|
31
|
+
File.open(@r10k_config) do |file|
|
|
32
|
+
# make sure we don't have any concurrency issues
|
|
33
|
+
file.flock(File::LOCK_EX)
|
|
34
|
+
|
|
35
|
+
r10k = YAML.load_file(@r10k_config)
|
|
36
|
+
r10k['sources'][username] = {
|
|
37
|
+
'remote' => sprintf(@pattern, username),
|
|
38
|
+
'basedir' => @environments,
|
|
39
|
+
'prefix' => (@repomodel == :peruser),
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# Ruby 1.8.7, why don't you just go away now
|
|
43
|
+
File.open(@r10k_config, 'w') { |f| f.write(r10k.to_yaml) }
|
|
44
|
+
$logger.info "Created r10k source for #{username}"
|
|
45
|
+
end
|
|
46
|
+
rescue => e
|
|
47
|
+
$logger.error "Cannot create r10k source for #{username}"
|
|
48
|
+
$logger.error e.backtrace
|
|
49
|
+
return false
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def delete(username)
|
|
56
|
+
begin
|
|
57
|
+
environment = "#{@environments}/#{Puppetfactory::Helpers.environment_name(username)}"
|
|
58
|
+
FileUtils.rm_rf environment
|
|
59
|
+
|
|
60
|
+
# also delete any prefixed environments. Is this even a good idea?
|
|
61
|
+
FileUtils.rm_rf "#{@environments}/#{username}_*" if @repomodel == :peruser
|
|
62
|
+
|
|
63
|
+
File.open(@r10k_config) do |file|
|
|
64
|
+
# make sure we don't have any concurrency issues
|
|
65
|
+
file.flock(File::LOCK_EX)
|
|
66
|
+
|
|
67
|
+
r10k = YAML.load_file(@r10k_config)
|
|
68
|
+
r10k['sources'].delete username
|
|
69
|
+
|
|
70
|
+
# Ruby 1.8.7, why don't you just go away now
|
|
71
|
+
File.open(@r10k_config, 'w') { |f| f.write(r10k.to_yaml) }
|
|
72
|
+
$logger.info "Created r10k source for #{username}"
|
|
73
|
+
end
|
|
74
|
+
rescue => e
|
|
75
|
+
$logger.error "Cannot remove r10k source for #{username}"
|
|
76
|
+
$logger.error e.backtrace
|
|
77
|
+
return false
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
true
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def deploy(username)
|
|
84
|
+
environment = Puppetfactory::Helpers.environment_name(username)
|
|
85
|
+
|
|
86
|
+
output, status = Open3.capture2e('r10k', 'deploy', 'environment', environment)
|
|
87
|
+
unless status.success?
|
|
88
|
+
$logger.error "Failed to deploy environment #{environment} for #{username}"
|
|
89
|
+
$logger.error output
|
|
90
|
+
return false
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
$logger.info "Deployed environment #{environment} for #{username}"
|
|
94
|
+
true
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def redeploy(username)
|
|
98
|
+
begin
|
|
99
|
+
if username == 'production'
|
|
100
|
+
raise "Can't redeploy production environment"
|
|
101
|
+
end
|
|
102
|
+
delete(username)
|
|
103
|
+
deploy(username)
|
|
104
|
+
|
|
105
|
+
rescue => e
|
|
106
|
+
raise "Error redeploying environment #{username}: #{e.message}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
true
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|