puppetfactory 0.5.9 → 0.6.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 +4 -4
- data/bin/puppetfactory +5 -2
- data/lib/puppetfactory.rb +31 -8
- data/lib/puppetfactory/plugins/docker.rb +1 -1
- data/lib/puppetfactory/plugins/gitea.rb +94 -33
- data/public/css/style.css +78 -104
- data/public/explain-git-with-d3/css/explaingit.css +1 -0
- data/public/images/Puppet-Logo-Mark-Amber-sm.png +0 -0
- data/public/js/scripts.js +7 -7
- data/public/js/usermanagement.js +9 -15
- data/views/currentuser.erb +51 -0
- data/views/index.erb +44 -22
- data/views/logs.erb +1 -10
- data/views/newuser.erb +19 -0
- data/views/shell.erb +31 -31
- data/views/userlogin.erb +9 -0
- data/views/users.erb +0 -68
- metadata +6 -5
- data/public/images/Puppet-Logo-Amber-White-sm.png +0 -0
- data/public/js/loginscripts.js +0 -18
- data/views/home.erb +0 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f68142c666caae7ed6041926b898235c8ec86adb
|
4
|
+
data.tar.gz: 3e44a08a9800fe697b19d0e310f04324e26bb636
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a13501a324ee2f1657437b6c3af2da79a9daa79f95556e29597fe80157bf43a21e2429cf36865dc5458cc52f0e7a716bf965288517a627f2b14ce1c2c11bec9
|
7
|
+
data.tar.gz: 676a0e83e781edea7579224602899865edf35019b9998340ec15504afbe827f1f4fb572ee0689555c902def65f0a84f19dbdc4d364467794f22ee542af53c476
|
data/bin/puppetfactory
CHANGED
@@ -85,7 +85,7 @@ options[:gituser] ||= 'puppetlabs'
|
|
85
85
|
options[:controlrepo] ||= 'control-repo.git'
|
86
86
|
options[:repomodel] ||= :single
|
87
87
|
|
88
|
-
options[:plugins] ||= [:ShellUser, :Logs]
|
88
|
+
options[:plugins] ||= [:ShellUser, :Logs, :LoginShell]
|
89
89
|
|
90
90
|
def validate(options, option, values)
|
91
91
|
unless values.include? options[option]
|
@@ -106,7 +106,10 @@ $logger.formatter = proc { |severity,datetime,progname,msg| "[#{datetime}] #{sev
|
|
106
106
|
|
107
107
|
# if no arguments, start up the server
|
108
108
|
if ARGV.size == 0
|
109
|
-
|
109
|
+
# TODO: remove this insane timeout once we have a progressive user creation dialog
|
110
|
+
Puppetfactory.run!(options) do |server|
|
111
|
+
server.timeout = 180
|
112
|
+
end
|
110
113
|
|
111
114
|
# opts = {
|
112
115
|
# :Port => 8000,
|
data/lib/puppetfactory.rb
CHANGED
@@ -26,7 +26,7 @@ class Puppetfactory < Sinatra::Base
|
|
26
26
|
|
27
27
|
configure :production, :development do
|
28
28
|
enable :logging
|
29
|
-
use Rack::Session::Cookie,
|
29
|
+
use Rack::Session::Cookie,
|
30
30
|
:key => 'puppetfactory.session',
|
31
31
|
:path => '/',
|
32
32
|
:expire_after => 2592000, # In seconds
|
@@ -37,7 +37,7 @@ class Puppetfactory < Sinatra::Base
|
|
37
37
|
# IE is cache happy. Let's make that go away.
|
38
38
|
cache_control :no_cache, :max_age => 0
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def initialize(app=nil)
|
42
42
|
super(app)
|
43
43
|
|
@@ -66,14 +66,11 @@ class Puppetfactory < Sinatra::Base
|
|
66
66
|
# UI tab endpoints
|
67
67
|
get '/' do
|
68
68
|
@tabs = merge(plugins(:tabs, privileged?))
|
69
|
+
@current = merge(plugins(:userinfo, session[:username], true)) if session.include? :username
|
69
70
|
|
70
71
|
erb :index
|
71
72
|
end
|
72
73
|
|
73
|
-
get '/home' do
|
74
|
-
erb :home
|
75
|
-
end
|
76
|
-
|
77
74
|
get '/users' do
|
78
75
|
@users = load_users()
|
79
76
|
@current = merge(plugins(:userinfo, session[:username], true)) if session.include? :username
|
@@ -88,16 +85,38 @@ class Puppetfactory < Sinatra::Base
|
|
88
85
|
|
89
86
|
# set the currently active user. This should probably be a PUT action.
|
90
87
|
get '/users/active/:username' do |username|
|
88
|
+
username ||= myParams[user]
|
89
|
+
|
90
|
+
users ||= load_users()
|
91
|
+
|
92
|
+
unless users.include?(username)
|
93
|
+
return {
|
94
|
+
"status" => "failure",
|
95
|
+
"message" => "invalid user"
|
96
|
+
}.to_json
|
97
|
+
end
|
98
|
+
|
91
99
|
session[:username] = username
|
92
100
|
{"status" => "ok"}.to_json
|
101
|
+
redirect '/'
|
102
|
+
end
|
103
|
+
|
104
|
+
get '/users/deactive' do
|
105
|
+
session.delete :username
|
106
|
+
redirect '/'
|
93
107
|
end
|
94
108
|
|
95
109
|
# admin login
|
96
|
-
get '/login' do
|
110
|
+
get '/admin-login' do
|
97
111
|
protected!
|
98
112
|
redirect '/'
|
99
113
|
end
|
100
114
|
|
115
|
+
get '/admin-logout' do
|
116
|
+
remove_privileges!
|
117
|
+
redirect '/'
|
118
|
+
end
|
119
|
+
|
101
120
|
# create a new username with the default password.
|
102
121
|
get '/new/:username' do |username|
|
103
122
|
protected!
|
@@ -300,10 +319,14 @@ class Puppetfactory < Sinatra::Base
|
|
300
319
|
session[:privileges] = 'admin'
|
301
320
|
true
|
302
321
|
else
|
303
|
-
|
322
|
+
remove_privileges!
|
304
323
|
false
|
305
324
|
end
|
306
325
|
end
|
307
326
|
|
327
|
+
def remove_privileges!
|
328
|
+
session.delete :privileges
|
329
|
+
end
|
330
|
+
|
308
331
|
end
|
309
332
|
end
|
@@ -33,7 +33,7 @@ class Puppetfactory::Plugins::Docker < Puppetfactory::Plugins
|
|
33
33
|
"/var/yum:/var/yum",
|
34
34
|
"/var/cache:/var/cache",
|
35
35
|
"/etc/pki/rpm-gpg:/etc/pki/rpm-gpg",
|
36
|
-
"/etc/yum.repos.d:/etc/yum.repos.d",
|
36
|
+
# "/etc/yum.repos.d:/etc/yum.repos.d", # we can't share this because of pe_repo.repo
|
37
37
|
"/opt/puppetlabs/server:/opt/puppetlabs/server",
|
38
38
|
"/home/#{username}/puppet:#{@confdir}",
|
39
39
|
"/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'fileutils'
|
3
|
+
require 'restclient'
|
3
4
|
require 'puppetfactory'
|
4
5
|
|
5
6
|
class Puppetfactory::Plugins::Gitea < Puppetfactory::Plugins
|
@@ -7,49 +8,40 @@ class Puppetfactory::Plugins::Gitea < Puppetfactory::Plugins
|
|
7
8
|
def initialize(options)
|
8
9
|
super(options)
|
9
10
|
|
11
|
+
@cache_dir = '/var/cache/puppetfactory/gitea'
|
12
|
+
@lockfile = '/var/cache/puppetfactory/gitea.lock'
|
10
13
|
@suffix = options[:usersuffix]
|
11
14
|
@controlrepo = options[:controlrepo]
|
12
15
|
@reponame = File.basename(@controlrepo, '.git')
|
13
|
-
@
|
16
|
+
@repopath = "#{@cache_dir}/#{@reponame}"
|
17
|
+
@gitea_cmd = options[:gitea_cmd] || '/home/git/go/bin/gitea'
|
14
18
|
@admin_username = options[:gitea_admin_username] || 'root'
|
15
19
|
@admin_password = options[:gitea_admin_password] || 'puppetlabs'
|
16
|
-
@gitea_port = options[:gitea_port]
|
20
|
+
@gitea_port = options[:gitea_port] || '3000'
|
21
|
+
@gitea_user = options[:gitea_user] || 'git'
|
22
|
+
@gitea_homedir = Dir.home(@gitea_user)
|
17
23
|
|
18
|
-
@cache_dir
|
19
|
-
|
20
|
-
if (!File.directory?("#{@cache_dir}/#{@reponame}"))
|
21
|
-
$logger.info "Migrating repository #{@reponame}"
|
22
|
-
begin
|
23
|
-
`curl -su "#{@admin_username}:#{@admin_password}" --data "clone_addr=https://github.com/puppetlabs-education/#{@controlrepo}&uid=1&repo_name=#{@reponame}" http://localhost:#{@gitea_port}/api/v1/repos/migrate`
|
24
|
-
FileUtils::mkdir_p @cache_dir
|
25
|
-
Dir.chdir(@cache_dir) do
|
26
|
-
`git clone --depth 1 http://#{@admin_username}:#{@admin_password}@localhost:#{@gitea_port}/#{@admin_username}/#{@controlrepo}`
|
27
|
-
end
|
28
|
-
rescue => e
|
29
|
-
$logger.error "Error migrating repository: #{e.message}"
|
30
|
-
return false
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def add_collaborator(owner, repo, username, permission)
|
36
|
-
`curl -su "#{@admin_username}:#{@admin_password}" -X PUT -H "Content-Type: application/json" -d '{"permissions":"#{permission}"}' http://localhost:#{@gitea_port}/api/v1/repos/#{owner}/#{repo}/collaborators/#{username}`
|
37
|
-
end
|
38
|
-
|
39
|
-
def make_branch(username)
|
40
|
-
Dir.chdir("#{@cache_dir}/#{@reponame}") do
|
41
|
-
`git checkout -b #{username} && git push origin #{username}`
|
42
|
-
end
|
24
|
+
migrate_repo! unless File.directory?(@cache_dir)
|
43
25
|
end
|
44
26
|
|
45
27
|
def create(username, password)
|
46
28
|
begin
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
29
|
+
# since we're changing directories, none of this can be done concurrently; lock it all.
|
30
|
+
#
|
31
|
+
# TODO: consider forking worker processes so that CWD doesn't leak between threads.
|
32
|
+
File.open(@lockfile, 'w') do |file|
|
33
|
+
file.flock(File::LOCK_EX)
|
34
|
+
|
35
|
+
make_user(username, password)
|
36
|
+
$logger.debug "Created Gitea user #{username}."
|
37
|
+
make_branch(username)
|
38
|
+
$logger.debug "Created Gitea branch #{username}."
|
39
|
+
add_collaborator(@admin_username, @reponame, username, 'write')
|
40
|
+
$logger.info "Created Gitea collaborator #{username}."
|
41
|
+
end
|
51
42
|
rescue => e
|
52
|
-
$logger.error "Error
|
43
|
+
$logger.error "Error configuring Gitea for #{username}: #{e.message}"
|
44
|
+
$logger.error e.backtrace.join("\n")
|
53
45
|
return false
|
54
46
|
end
|
55
47
|
|
@@ -58,7 +50,7 @@ class Puppetfactory::Plugins::Gitea < Puppetfactory::Plugins
|
|
58
50
|
|
59
51
|
def delete(username)
|
60
52
|
begin
|
61
|
-
|
53
|
+
remove_user(username)
|
62
54
|
$logger.info "Removed Gitea user #{username}."
|
63
55
|
rescue => e
|
64
56
|
$logger.error "Error removing Gitea user #{username}: #{e.message}"
|
@@ -68,4 +60,73 @@ class Puppetfactory::Plugins::Gitea < Puppetfactory::Plugins
|
|
68
60
|
true
|
69
61
|
end
|
70
62
|
|
63
|
+
private
|
64
|
+
def migrate_repo!
|
65
|
+
FileUtils::mkdir_p @cache_dir
|
66
|
+
$logger.info "Migrating repository #{@reponame}"
|
67
|
+
begin
|
68
|
+
RestClient.post("http://#{@admin_username}:#{@admin_password}@localhost:#{@gitea_port}/api/v1/repos/migrate", {
|
69
|
+
'clone_addr' => "https://github.com/puppetlabs-education/#{@controlrepo}",
|
70
|
+
'uid' => 1,
|
71
|
+
'repo_name' => @reponame,
|
72
|
+
})
|
73
|
+
|
74
|
+
# make sure the server has time to finish cloning from GitHub before cloning
|
75
|
+
sleep 5
|
76
|
+
|
77
|
+
Dir.chdir(@cache_dir) do
|
78
|
+
repo_uri = "http://#{@admin_username}:#{@admin_password}@localhost:#{@gitea_port}/#{@admin_username}/#{@controlrepo}"
|
79
|
+
output, status = Open3.capture2e('git', 'clone', '--depth', '1', repo_uri)
|
80
|
+
raise output unless status.success?
|
81
|
+
end
|
82
|
+
|
83
|
+
rescue => e
|
84
|
+
$logger.error "Error migrating repository: #{e.message}"
|
85
|
+
$logger.error e.backtrace.join("\n")
|
86
|
+
return false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def make_user(username, password)
|
91
|
+
Dir.chdir(@gitea_homedir) do
|
92
|
+
uid = Etc.getpwnam(@gitea_user).uid
|
93
|
+
pid = Process.fork do
|
94
|
+
ENV['USER'] = @gitea_user
|
95
|
+
Process.uid = uid
|
96
|
+
Process.euid = uid
|
97
|
+
|
98
|
+
output, status = Open3.capture2e(@gitea_cmd, 'admin', 'create-user',
|
99
|
+
'--name', username,
|
100
|
+
'--password', password,
|
101
|
+
'--email', "#{username}@#{@suffix}")
|
102
|
+
|
103
|
+
$logger.error output unless status.success?
|
104
|
+
exit status.exitstatus
|
105
|
+
end
|
106
|
+
|
107
|
+
pid, status = Process.wait2(pid)
|
108
|
+
raise "Error creating Gitea user #{username}" unless status.success?
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def add_collaborator(owner, repo, username, permission)
|
113
|
+
repo_uri = "http://#{@admin_username}:#{@admin_password}@localhost:#{@gitea_port}/api/v1/repos/#{owner}/#{repo}/collaborators/#{username}"
|
114
|
+
RestClient.put(repo_uri, {'permissions' => permission}.to_json)
|
115
|
+
end
|
116
|
+
|
117
|
+
def make_branch(username)
|
118
|
+
Dir.chdir(@repopath) do
|
119
|
+
# use --force in case the branch already exists
|
120
|
+
output, status = Open3.capture2e('git', 'branch', '--force', username)
|
121
|
+
raise output unless status.success?
|
122
|
+
|
123
|
+
output, status = Open3.capture2e('git', 'push', 'origin', username)
|
124
|
+
raise output unless status.success?
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def remove_user(username)
|
129
|
+
RestClient.delete("http://#{@admin_username}:#{@admin_password}@localhost:#{@gitea_port}/api/v1/admin/users/#{username}")
|
130
|
+
end
|
131
|
+
|
71
132
|
end
|
data/public/css/style.css
CHANGED
@@ -14,6 +14,16 @@ footer {
|
|
14
14
|
width: 100%;
|
15
15
|
}
|
16
16
|
|
17
|
+
hr {
|
18
|
+
border: none;
|
19
|
+
border-top: 2px solid #222222;
|
20
|
+
margin: 2em 0 1em;
|
21
|
+
}
|
22
|
+
|
23
|
+
article {
|
24
|
+
margin: 6em 4em 2em 4em;
|
25
|
+
}
|
26
|
+
|
17
27
|
a {
|
18
28
|
text-decoration: none;
|
19
29
|
color: #3880ff;
|
@@ -28,24 +38,31 @@ button:focus {
|
|
28
38
|
outline: none;
|
29
39
|
}
|
30
40
|
|
41
|
+
code {
|
42
|
+
background-color: #ddd;
|
43
|
+
border-bottom: 2px dotted #aaa;
|
44
|
+
padding: 0.25em;
|
45
|
+
}
|
46
|
+
|
31
47
|
header {
|
32
48
|
height: 4em;
|
33
49
|
top: 0;
|
34
50
|
}
|
35
51
|
|
52
|
+
header ul,
|
53
|
+
header li,
|
54
|
+
header a {
|
55
|
+
display: inline-block;
|
56
|
+
}
|
57
|
+
|
36
58
|
header ul {
|
37
59
|
margin: 0;
|
38
60
|
padding: 0;
|
39
61
|
list-style: none;
|
40
62
|
}
|
41
63
|
|
42
|
-
header
|
43
|
-
|
44
|
-
padding: 1.2em 2em;
|
45
|
-
}
|
46
|
-
|
47
|
-
header li a {
|
48
|
-
display: block;
|
64
|
+
header a {
|
65
|
+
margin: 1.2em 1em;
|
49
66
|
color: #ffffff;
|
50
67
|
}
|
51
68
|
|
@@ -55,13 +72,14 @@ a:hover {
|
|
55
72
|
|
56
73
|
header a:hover,
|
57
74
|
.ui-tabs-active a,
|
58
|
-
#login:hover {
|
75
|
+
#admin-login:hover {
|
59
76
|
color: #ffae1a;
|
60
77
|
border-color: #ffae1a;
|
61
78
|
}
|
62
79
|
|
63
80
|
input[type="button"],
|
64
|
-
.ui-dialog button
|
81
|
+
.ui-dialog button,
|
82
|
+
.button {
|
65
83
|
padding: .5em 1em;
|
66
84
|
border: none;
|
67
85
|
background-color: #ffae1a;
|
@@ -73,10 +91,6 @@ input[type="button"]:hover {
|
|
73
91
|
opacity: .7;
|
74
92
|
}
|
75
93
|
|
76
|
-
article {
|
77
|
-
margin: 6em 4em 2em 4em;
|
78
|
-
}
|
79
|
-
|
80
94
|
li {
|
81
95
|
margin-bottom: .5em;
|
82
96
|
}
|
@@ -95,10 +109,29 @@ tr:nth-child(2n+2) {
|
|
95
109
|
background: #dedede;
|
96
110
|
}
|
97
111
|
|
98
|
-
|
99
|
-
|
112
|
+
input[type="text"],
|
113
|
+
input[type="password"] {
|
114
|
+
font-size: .8em;
|
115
|
+
width: 100%;
|
116
|
+
max-width: 100%;
|
117
|
+
padding: 8px 12px;
|
118
|
+
border: 2px solid #dedede;
|
119
|
+
outline: none;
|
120
|
+
}
|
121
|
+
|
122
|
+
input.fail {
|
123
|
+
background-color: #f88484;
|
124
|
+
border-color: #d63700;
|
100
125
|
}
|
101
126
|
|
127
|
+
.flexrow { display: flex; }
|
128
|
+
|
129
|
+
.flex-7 { flex: 7; }
|
130
|
+
.flex-3 { flex: 3; }
|
131
|
+
|
132
|
+
.flex-right { margin-left: 1em; }
|
133
|
+
.flex-left { margin-right: 1em; }
|
134
|
+
|
102
135
|
.ui-dialog {
|
103
136
|
background-color: #ffffff;
|
104
137
|
padding: 1em 2em;
|
@@ -111,85 +144,42 @@ tr:nth-child(2n+2) {
|
|
111
144
|
|
112
145
|
#nav-logo {
|
113
146
|
float: left;
|
114
|
-
padding: 1em 2em;
|
147
|
+
padding: 1em 1em 1em 2em;
|
115
148
|
height: 2em;
|
116
149
|
}
|
117
150
|
|
118
|
-
#login
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
#userslist,
|
124
|
-
#shellwrapper {
|
125
|
-
display: none;
|
126
|
-
}
|
127
|
-
|
128
|
-
#usercontent {
|
129
|
-
position: relative;
|
130
|
-
}
|
131
|
-
|
132
|
-
#newuserwrapper {
|
133
|
-
margin-top: 2em;
|
151
|
+
#admin-login,
|
152
|
+
#admin-logout {
|
153
|
+
float: right;
|
154
|
+
margin: 1.2em 2em;
|
155
|
+
color: #ffffff;
|
134
156
|
}
|
135
157
|
|
136
|
-
#
|
158
|
+
#userslist {
|
137
159
|
display: none;
|
138
|
-
margin-top: 0.5em;
|
139
|
-
padding: 1em;
|
140
160
|
}
|
141
161
|
|
142
|
-
#
|
162
|
+
#user-wrapper div {
|
143
163
|
margin: .5em 0;
|
144
164
|
}
|
145
165
|
|
146
|
-
#newuser.processing,
|
147
166
|
#newuser.processing input {
|
148
167
|
background: #dedede;
|
149
|
-
|
150
|
-
border: none;
|
151
|
-
}
|
152
|
-
|
153
|
-
#newuser.processing {
|
154
|
-
border-color: #565656;
|
155
|
-
}
|
156
|
-
|
157
|
-
#newuser label {
|
158
|
-
display: inline-block;
|
159
|
-
width: 6em;
|
168
|
+
border: #4e4e4e;
|
160
169
|
}
|
161
170
|
|
162
|
-
#
|
163
|
-
|
164
|
-
font-family: 'Calibre-Regular', sans-serif;
|
165
|
-
font-size: 1em;
|
166
|
-
display: inline-block;
|
167
|
-
box-sizing: border-box;
|
168
|
-
width: 25%;
|
169
|
-
max-width: 100%;
|
170
|
-
padding: 8px 12px;
|
171
|
-
line-height: 1em;
|
172
|
-
border: 2px solid #dedede;
|
173
|
-
outline: none;
|
174
|
-
}
|
175
|
-
|
176
|
-
#newuser input.fail {
|
177
|
-
background: #f88484;
|
171
|
+
#user-wrapper h3 {
|
172
|
+
margin-top: 0;
|
178
173
|
}
|
179
174
|
|
180
175
|
#currentuser {
|
181
|
-
margin-bottom:
|
176
|
+
margin-bottom: 1em;
|
182
177
|
}
|
183
178
|
|
184
179
|
#currentuser th.header {
|
185
|
-
width: 10%;
|
186
|
-
white-space: nowrap;
|
187
180
|
text-align: right;
|
188
181
|
padding-right: 1em;
|
189
182
|
}
|
190
|
-
#currentuser tr.actions {
|
191
|
-
text-align: right;
|
192
|
-
}
|
193
183
|
|
194
184
|
#users {
|
195
185
|
margin-top: 1em;
|
@@ -203,42 +193,20 @@ tr:nth-child(2n+2) {
|
|
203
193
|
text-align: center;
|
204
194
|
}
|
205
195
|
|
206
|
-
#users td.select {
|
207
|
-
font-size: 0.8em;
|
208
|
-
}
|
209
|
-
|
210
196
|
#console {
|
211
197
|
width: 100%;
|
212
|
-
height:
|
213
|
-
resize: vertical;
|
214
|
-
}
|
215
|
-
|
216
|
-
#shell code {
|
217
|
-
background-color: #ddd;
|
218
|
-
border-bottom: 2px dotted #aaa;
|
219
|
-
padding: 0.25em;
|
198
|
+
height: 36em;
|
220
199
|
}
|
221
200
|
|
222
|
-
#alternate,
|
223
201
|
#explanation {
|
224
202
|
display: none;
|
225
203
|
}
|
226
204
|
|
227
|
-
#
|
228
|
-
float: right;
|
229
|
-
margin-left: 0.5em;
|
230
|
-
}
|
231
|
-
|
232
|
-
#dashboard {
|
233
|
-
|
234
|
-
}
|
235
|
-
|
236
|
-
#dashboard #notifications {
|
237
|
-
font-size: 0.5em;
|
205
|
+
#notifications {
|
238
206
|
color: #666;
|
239
207
|
}
|
240
208
|
|
241
|
-
#
|
209
|
+
#notifications.fail {
|
242
210
|
font-weight: bold;
|
243
211
|
background-color: red;
|
244
212
|
border: 1px solid black;
|
@@ -246,18 +214,13 @@ tr:nth-child(2n+2) {
|
|
246
214
|
padding: 0.25em 0.5em;
|
247
215
|
}
|
248
216
|
|
249
|
-
#
|
217
|
+
#tools {
|
250
218
|
float: right;
|
251
219
|
top: 1em;
|
252
|
-
font-size: 0.8em;
|
253
220
|
margin-bottom: 0.5em;
|
254
221
|
}
|
255
222
|
|
256
|
-
#
|
257
|
-
font-size: 0.8em;
|
258
|
-
}
|
259
|
-
|
260
|
-
#dashboard #tools * .ui-button-text {
|
223
|
+
#tools * .ui-button-text {
|
261
224
|
padding-top: 0.25em;
|
262
225
|
padding-bottom: 0.25em;
|
263
226
|
}
|
@@ -274,7 +237,6 @@ tr:nth-child(2n+2) {
|
|
274
237
|
background-color: #ffdddd;
|
275
238
|
border-radius: 0.25em;
|
276
239
|
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.25) inset;
|
277
|
-
font-size: 0.8em;
|
278
240
|
}
|
279
241
|
|
280
242
|
#dashboard .gutter .label {
|
@@ -292,7 +254,6 @@ tr:nth-child(2n+2) {
|
|
292
254
|
}
|
293
255
|
|
294
256
|
#dashboard .completed a {
|
295
|
-
font-size: 0.5em;
|
296
257
|
text-decoration: none;
|
297
258
|
}
|
298
259
|
|
@@ -300,7 +261,20 @@ tr:nth-child(2n+2) {
|
|
300
261
|
border-bottom: 2px solid black;
|
301
262
|
}
|
302
263
|
|
264
|
+
#logs .data {
|
265
|
+
font-family: monospace;
|
266
|
+
font-size: 1.2em;
|
267
|
+
white-space: pre-wrap;
|
268
|
+
}
|
269
|
+
|
303
270
|
#gitviz {
|
304
271
|
width: 100%;
|
305
272
|
min-height: 600px;
|
306
273
|
}
|
274
|
+
|
275
|
+
@media ( max-width: 1024px ) {
|
276
|
+
.flexrow { flex-direction: column; }
|
277
|
+
|
278
|
+
.flex-right { margin-left: 0; }
|
279
|
+
.flex-left { margin-right: 0; }
|
280
|
+
}
|
Binary file
|
data/public/js/scripts.js
CHANGED
@@ -16,12 +16,6 @@ $(document).ready(function(){
|
|
16
16
|
return keepLoading;
|
17
17
|
},
|
18
18
|
});
|
19
|
-
|
20
|
-
$('#login').button({
|
21
|
-
icons: {
|
22
|
-
primary: "ui-icon-locked"
|
23
|
-
}
|
24
|
-
});
|
25
19
|
});
|
26
20
|
|
27
21
|
function updatePage(name) {
|
@@ -32,5 +26,11 @@ function updatePage(name) {
|
|
32
26
|
var idx = $("#tabs").tabs("option","active");
|
33
27
|
}
|
34
28
|
|
35
|
-
|
29
|
+
// force a hard reload if we're already on the desired page
|
30
|
+
if ($("#tabs").tabs("option","active") == idx) {
|
31
|
+
location.reload(true);
|
32
|
+
}
|
33
|
+
else {
|
34
|
+
$("#tabs").tabs('load', idx);
|
35
|
+
}
|
36
36
|
}
|
data/public/js/usermanagement.js
CHANGED
@@ -9,19 +9,6 @@ $(document).ready(function(){
|
|
9
9
|
return true;
|
10
10
|
};
|
11
11
|
|
12
|
-
function open() {
|
13
|
-
$('#showuser').hide();
|
14
|
-
$('#newuserwrapper').addClass("open");
|
15
|
-
$('#newuser').slideDown("fast");
|
16
|
-
$('#user').focus();
|
17
|
-
}
|
18
|
-
|
19
|
-
function close() {
|
20
|
-
$('#showuser').show();
|
21
|
-
$('#newuserwrapper').removeClass("open");
|
22
|
-
$('#newuser').hide();
|
23
|
-
}
|
24
|
-
|
25
12
|
function start_processing() {
|
26
13
|
$('#newuser input[type=button]').attr("disabled", true);
|
27
14
|
$('#newuser').addClass("processing");
|
@@ -48,15 +35,22 @@ $(document).ready(function(){
|
|
48
35
|
close();
|
49
36
|
});
|
50
37
|
|
51
|
-
$('#users .select a').click(function(event){
|
38
|
+
$('#users .select a, #user-logout').click(function(event){
|
52
39
|
event.preventDefault();
|
53
40
|
var action = $(this).attr('href');
|
54
|
-
|
55
41
|
$.get(action, function(data) {
|
56
42
|
updatePage();
|
57
43
|
});
|
58
44
|
});
|
59
45
|
|
46
|
+
$('#login-submit').click(function (event) {
|
47
|
+
event.preventDefault();
|
48
|
+
var action = $(this).attr('href');
|
49
|
+
var user = $('#login-user').val();
|
50
|
+
|
51
|
+
$.get(action, {user: user});
|
52
|
+
});
|
53
|
+
|
60
54
|
// save the new user
|
61
55
|
$('#save').click(function(){
|
62
56
|
var username = $('#user').val();
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<div id="currentuser-wrapper">
|
2
|
+
<% if @current %>
|
3
|
+
<h3>Selected User</h3>
|
4
|
+
<table id="currentuser">
|
5
|
+
<tr><th class="header">Username:</th> <td><%= @current[:username] %></td></tr>
|
6
|
+
<tr><th class="header">Certname:</th> <td><%= @current[:certname] %></td></tr>
|
7
|
+
<% if @current[:port] -%>
|
8
|
+
<tr><th class="header">Webserver URL:</th> <td><a href="/port/<%= @current[:port] %>/"><%= @current[:url] %></a></td></tr>
|
9
|
+
<% end -%>
|
10
|
+
<% if @current[:container_status] -%>
|
11
|
+
<tr><th class="header">Container:</th> <td><%= @current[:container_status]['Description'] %></td></tr>
|
12
|
+
<% end -%>
|
13
|
+
<% if @current[:node_group_url] -%>
|
14
|
+
<tr><th class="header">Node Group:</th> <td><a href="https://<%= request.host %>/<%= @current[:node_group_url] %>" target="_console">Console login</a></td></tr>
|
15
|
+
<% end -%>
|
16
|
+
<% if @current[:controlrepo] -%>
|
17
|
+
<tr><th class="header">Control Repo:</th> <td><a href="<%= @current[:controlrepo] %>" target="_repository"><%= @current[:controlrepo] %></a></td></tr>
|
18
|
+
<% end -%>
|
19
|
+
<% if @current[:latestcommit] -%>
|
20
|
+
<tr><th class="header">Latest Commit:</th>
|
21
|
+
<td>
|
22
|
+
<a href="<%= @current[:latestcommit][:url] %>" target="_repository"><%= @current[:latestcommit][:message] %></a>
|
23
|
+
<small>(<%= @current[:latestcommit][:time] %>)</small>
|
24
|
+
</td></tr>
|
25
|
+
<% end -%>
|
26
|
+
<% if settings.plugins.include? :Dashboard -%>
|
27
|
+
<tr><th class="header">Spec Tests:</th> <td><a href="/dashboard/details/<%= @current[:username] %>" target="_results">results</a> <small>(may not always be available)</small></td></tr>
|
28
|
+
<% end -%>
|
29
|
+
<% if @current[:tree] -%>
|
30
|
+
<tr>
|
31
|
+
<th class="header">Environment Structure:</th>
|
32
|
+
<td><div id="tree"></div></td>
|
33
|
+
</tr>
|
34
|
+
<% end -%>
|
35
|
+
</table>
|
36
|
+
<% if action_enabled? :deploy -%>
|
37
|
+
<i class="fa"></i><input type="button" id="deploy" data-user="<%= @current[:username] %>" value="Deploy Environment">
|
38
|
+
<% end -%>
|
39
|
+
<div>
|
40
|
+
<a class="user-logout" href="/users/deactive">Logout</a>
|
41
|
+
</div>
|
42
|
+
<% end %>
|
43
|
+
|
44
|
+
<% if @current and @current[:tree] %>
|
45
|
+
<script type="text/javascript">
|
46
|
+
$(document).ready(function() {
|
47
|
+
$('#tree').jstree({ 'core': { 'data': <%= @current[:tree] %> } });
|
48
|
+
});
|
49
|
+
</script>
|
50
|
+
<% end %>
|
51
|
+
</div>
|
data/views/index.erb
CHANGED
@@ -1,37 +1,59 @@
|
|
1
1
|
<html>
|
2
2
|
<head>
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
<title>PuppetFactory</title>
|
4
|
+
<link rel="stylesheet" type="text/css" href="font-awesome/css/font-awesome.min.css">
|
5
|
+
<link rel="stylesheet" type="text/css" href="jstree-3.3.3/themes/default/style.min.css" />
|
6
|
+
<link rel="stylesheet" type="text/css" href="css/style.css" />
|
7
|
+
<script type="text/javascript" src="js/jquery.js"></script>
|
8
|
+
<script type="text/javascript" src="js/jquery-ui.min.js"></script>
|
9
|
+
<script type="text/javascript" src="js/scripts.js"></script>
|
10
|
+
<script type="text/javascript" src="js/jquery.activity-indicator-1.0.0.min.js"></script>
|
11
|
+
<script type="text/javascript" src="jstree-3.3.3/jstree.min.js"></script>
|
12
|
+
<script type="text/javascript" src="js/usermanagement.js"></script>
|
12
13
|
</head>
|
13
14
|
<body>
|
14
15
|
<div id="tabs">
|
15
16
|
<header>
|
17
|
+
<img src="/images/Puppet-Logo-Mark-Amber-sm.png" alt="logo" id="nav-logo">
|
16
18
|
<ul>
|
17
|
-
<
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
<li><a href="#home" class="cache">Home</a></li>
|
20
|
+
<% if privileged? %>
|
21
|
+
<li><a href="/users">Users</a></li>
|
22
|
+
<% @tabs.each do |url, title| %>
|
23
|
+
<li><a href="/<%= url %>"><%= title %></a></li>
|
24
|
+
<% end %>
|
23
25
|
<% end %>
|
24
|
-
<li class="right">
|
25
|
-
<% unless privileged? %><a href="/login" id="login">Admin Login</a><% end %>
|
26
|
-
</li>
|
27
26
|
</ul>
|
27
|
+
<a href="http://<%= request.host %>:9090" target="_presentation">Presentation</a>
|
28
|
+
<a href="https://<%= request.host %>" target="_console">PE Console</a>
|
29
|
+
<% if settings.plugins.include? :Gitea -%>
|
30
|
+
<a href="http://<%= request.host %>:3000" target="_gitea">Code Repository</a>
|
31
|
+
<% end %>
|
32
|
+
<% if privileged? %>
|
33
|
+
<a href="/admin-logout" id="admin-logout">Logout</a>
|
34
|
+
<% else %>
|
35
|
+
<a href="/admin-login" id="admin-login">Admin Login</a>
|
36
|
+
<% end %>
|
28
37
|
</header>
|
29
|
-
<article>
|
30
|
-
<
|
38
|
+
<article>
|
39
|
+
<h2>Puppet Classroom</h2>
|
31
40
|
<div id="home">
|
32
|
-
|
41
|
+
<div class="flexrow">
|
42
|
+
<div class="flex-7 flex-left">
|
43
|
+
<%= erb :shell %>
|
44
|
+
</div>
|
45
|
+
<div id="user-wrapper" class="flex-3 flex-right">
|
46
|
+
<% if @current %>
|
47
|
+
<%= erb :currentuser %>
|
48
|
+
<% else %>
|
49
|
+
<%= erb :newuser %>
|
50
|
+
<hr>
|
51
|
+
<%= erb :userlogin %>
|
52
|
+
<% end -%>
|
53
|
+
</div>
|
54
|
+
</div>
|
33
55
|
</div>
|
34
|
-
</article>
|
56
|
+
</article>
|
35
57
|
</div>
|
36
58
|
</body>
|
37
59
|
</html>
|
data/views/logs.erb
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
// use timeout instead of an interval so that in case of network error
|
16
16
|
// we don't end up with a queue of requests stacked up.
|
17
|
-
setTimeout(loadLogs, 5000);
|
17
|
+
setTimeout(function(){loadLogs}, 5000);
|
18
18
|
});
|
19
19
|
}
|
20
20
|
|
@@ -22,12 +22,3 @@
|
|
22
22
|
loadLogs(true);
|
23
23
|
});
|
24
24
|
</script>
|
25
|
-
|
26
|
-
<style>
|
27
|
-
#logs .data {
|
28
|
-
font-family: monospace;
|
29
|
-
white-space: pre-wrap;
|
30
|
-
height: 500px;
|
31
|
-
overflow-y: scroll;
|
32
|
-
}
|
33
|
-
</style>
|
data/views/newuser.erb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
<div id="newuser">
|
2
|
+
<h3>Create a new user</h3>
|
3
|
+
<div>
|
4
|
+
<label for="user">Username:</label><input type="text" id="user" value="" />
|
5
|
+
</div>
|
6
|
+
<div>
|
7
|
+
<label for="password">Password:</label><input type="password" id="password" value="" />
|
8
|
+
</div>
|
9
|
+
<div>
|
10
|
+
<label for="password2">Repeat:</label><input type="password" id="password2" value="" />
|
11
|
+
</div>
|
12
|
+
<div>
|
13
|
+
<label for="session">Session ID:</label><input type="text" id="session" value="" />
|
14
|
+
<p></p>
|
15
|
+
</div>
|
16
|
+
<div>
|
17
|
+
<input type="button" id="save" value="Submit" />
|
18
|
+
</div>
|
19
|
+
</div>
|
data/views/shell.erb
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
<div id="shell">
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
2
|
+
<% if @current %>
|
3
|
+
<iframe id="console" src="/shell/login/"></iframe>
|
4
|
+
<% else %>
|
5
|
+
<p>
|
6
|
+
Welcome to the Puppet Classroom. Please log in or create a user account.
|
7
|
+
</p>
|
8
|
+
<p>
|
9
|
+
We will provision a Puppet agent node for you and you'll use it to complete labs and
|
10
|
+
exercises. This node can be accessed through a web terminal once you've logged in.
|
11
|
+
</p>
|
12
|
+
<p>
|
13
|
+
If you prefer, you may also use any standard SSH client using the username
|
14
|
+
and password you specified. Some common SSH clients include:
|
15
|
+
<p>
|
16
|
+
<ul>
|
17
|
+
<li>
|
18
|
+
Built-in to Mac OSX and Linux:
|
19
|
+
<ol>
|
20
|
+
<li>Start Terminal.app or any terminal emulator to get to the command line</li>
|
21
|
+
<li>Run <code>ssh <%= request.host %></code></li>
|
22
|
+
</ol>
|
23
|
+
</li>
|
24
|
+
<li>
|
25
|
+
Windows:
|
16
26
|
<ul>
|
17
|
-
<li>
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
<li>Run <code>ssh <%= request.host %></code></li>
|
22
|
-
</ol>
|
23
|
-
</li>
|
24
|
-
<li>
|
25
|
-
Windows:
|
26
|
-
<ul>
|
27
|
-
<li><a href="http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe">PuTTY</a></li>
|
28
|
-
<li><a href="http://winscp.net/eng/download.php#download2" target="_new">WinSCP</a></li>
|
29
|
-
<li><a href="http://www.vandyke.com/download/securecrt/download.html" target="_new">SecureCRT</a></li>
|
30
|
-
</ul>
|
31
|
-
</li>
|
27
|
+
<li><a href="https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH">OpenSSH</a></li>
|
28
|
+
<li><a href="http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe">PuTTY</a></li>
|
29
|
+
<li><a href="http://winscp.net/eng/download.php#download2" target="_new">WinSCP</a></li>
|
30
|
+
<li><a href="http://www.vandyke.com/download/securecrt/download.html" target="_new">SecureCRT</a></li>
|
32
31
|
</ul>
|
33
|
-
</
|
32
|
+
</li>
|
33
|
+
</ul>
|
34
|
+
<% end -%>
|
34
35
|
</div>
|
35
|
-
<script type="text/javascript" src="js/loginscripts.js"></script>
|
data/views/userlogin.erb
ADDED
data/views/users.erb
CHANGED
@@ -1,43 +1,4 @@
|
|
1
1
|
<div id="usercontent">
|
2
|
-
|
3
|
-
<% if @current %>
|
4
|
-
<h3>Selected User</h3>
|
5
|
-
<table id="currentuser">
|
6
|
-
<tr><th class="header">Username:</th> <td><%= @current[:username] %></td></tr>
|
7
|
-
<tr><th class="header">Certname:</th> <td><%= @current[:certname] %></td></tr>
|
8
|
-
<% if @current[:port] -%>
|
9
|
-
<tr><th class="header">Webserver URL:</th> <td><a href="/port/<%= @current[:port] %>/"><%= @current[:url] %></a></td></tr>
|
10
|
-
<% end -%>
|
11
|
-
<% if @current[:container_status] -%>
|
12
|
-
<tr><th class="header">Container:</th> <td><%= @current[:container_status]['Description'] %></td></tr>
|
13
|
-
<% end -%>
|
14
|
-
<% if @current[:node_group_url] -%>
|
15
|
-
<tr><th class="header">Node Group:</th> <td><a href="https://<%= request.host %>/<%= @current[:node_group_url] %>" target="_console">Console login</a></td></tr>
|
16
|
-
<% end -%>
|
17
|
-
<% if @current[:controlrepo] -%>
|
18
|
-
<tr><th class="header">Control Repo:</th> <td><a href="<%= @current[:controlrepo] %>" target="_repository"><%= @current[:controlrepo] %></a></td></tr>
|
19
|
-
<% end -%>
|
20
|
-
<% if @current[:latestcommit] -%>
|
21
|
-
<tr><th class="header">Latest Commit:</th>
|
22
|
-
<td>
|
23
|
-
<a href="<%= @current[:latestcommit][:url] %>" target="_repository"><%= @current[:latestcommit][:message] %></a>
|
24
|
-
<small>(<%= @current[:latestcommit][:time] %>)</small>
|
25
|
-
</td></tr>
|
26
|
-
<% end -%>
|
27
|
-
<% if settings.plugins.include? :Dashboard -%>
|
28
|
-
<tr><th class="header">Spec Tests:</th> <td><a href="/dashboard/details/<%= @current[:username] %>" target="_results">results</a> <small>(may not always be available)</small></td></tr>
|
29
|
-
<% end -%>
|
30
|
-
<% if action_enabled? :deploy -%>
|
31
|
-
<tr class="actions"><td colspan=2><i class="fa"></i><input type="button" id="deploy" data-user="<%= @current[:username] %>" value="Deploy Environment"></td></tr>
|
32
|
-
<% end -%>
|
33
|
-
<% if @current[:tree] -%>
|
34
|
-
<tr>
|
35
|
-
<th class="header">Environment Structure:</th>
|
36
|
-
<td><div id="tree"></div></td>
|
37
|
-
</tr>
|
38
|
-
<% end -%>
|
39
|
-
</table>
|
40
|
-
<% end %>
|
41
2
|
<h3>All Users</h3>
|
42
3
|
<table id="users">
|
43
4
|
<tr class="header">
|
@@ -60,32 +21,3 @@
|
|
60
21
|
<% end %>
|
61
22
|
</table>
|
62
23
|
</div>
|
63
|
-
|
64
|
-
<div id="newuserwrapper">
|
65
|
-
<input type="button" id="showuser" value="+ New User" />
|
66
|
-
<div id="newuser">
|
67
|
-
<div>
|
68
|
-
<label for="user">Username:</label><input type="text" id="user" value="" />
|
69
|
-
</div>
|
70
|
-
<div>
|
71
|
-
<label for="password">Password:</label><input type="password" id="password" value="" />
|
72
|
-
</div>
|
73
|
-
<div>
|
74
|
-
<label for="password2">Repeat:</label><input type="password" id="password2" value="" />
|
75
|
-
</div>
|
76
|
-
<div>
|
77
|
-
<label for="session">Session ID:</label><input type="text" id="session" value="" />
|
78
|
-
</div>
|
79
|
-
<input type="button" id="hideuser" value="Cancel" />
|
80
|
-
<input type="button" id="save" value="Save" />
|
81
|
-
</div>
|
82
|
-
</div>
|
83
|
-
|
84
|
-
<script type="text/javascript" src="js/usermanagement.js"></script>
|
85
|
-
<% if @current and @current[:tree] %>
|
86
|
-
<script type="text/javascript">
|
87
|
-
$(document).ready(function() {
|
88
|
-
$('#tree').jstree({ 'core': { 'data': <%= @current[:tree] %> } });
|
89
|
-
});
|
90
|
-
</script>
|
91
|
-
<% end %>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppetfactory
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Ford
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-
|
13
|
+
date: 2017-10-31 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: sinatra
|
@@ -225,12 +225,11 @@ files:
|
|
225
225
|
- public/font-awesome/fonts/fontawesome-webfont.ttf
|
226
226
|
- public/font-awesome/fonts/fontawesome-webfont.woff
|
227
227
|
- public/font-awesome/fonts/fontawesome-webfont.woff2
|
228
|
-
- public/images/Puppet-Logo-Amber-
|
228
|
+
- public/images/Puppet-Logo-Mark-Amber-sm.png
|
229
229
|
- public/js/dashboard.js
|
230
230
|
- public/js/jquery-ui.min.js
|
231
231
|
- public/js/jquery.activity-indicator-1.0.0.min.js
|
232
232
|
- public/js/jquery.js
|
233
|
-
- public/js/loginscripts.js
|
234
233
|
- public/js/scripts.js
|
235
234
|
- public/js/usermanagement.js
|
236
235
|
- public/jstree-3.3.3/jstree.js
|
@@ -248,11 +247,13 @@ files:
|
|
248
247
|
- templates/init_scripts.erb
|
249
248
|
- templates/puppet.conf.erb
|
250
249
|
- templates/site.pp.erb
|
250
|
+
- views/currentuser.erb
|
251
251
|
- views/dashboard.erb
|
252
|
-
- views/home.erb
|
253
252
|
- views/index.erb
|
254
253
|
- views/logs.erb
|
254
|
+
- views/newuser.erb
|
255
255
|
- views/shell.erb
|
256
|
+
- views/userlogin.erb
|
256
257
|
- views/users.erb
|
257
258
|
homepage: https://github.com/puppetlabs/puppetfactory
|
258
259
|
licenses:
|
Binary file
|
data/public/js/loginscripts.js
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
$(document).ready(function(){
|
2
|
-
$('#show-alternate').click( function(e) {
|
3
|
-
e.preventDefault();
|
4
|
-
|
5
|
-
$( "#alternate" ).dialog({
|
6
|
-
title: $(this).attr("title"),
|
7
|
-
buttons: {
|
8
|
-
Ok: function() {
|
9
|
-
$( this ).dialog( "close" );
|
10
|
-
}
|
11
|
-
},
|
12
|
-
open: function () {
|
13
|
-
$(this).parent().find('button:nth-child(1)').focus();
|
14
|
-
},
|
15
|
-
width: '500px',
|
16
|
-
});
|
17
|
-
});
|
18
|
-
});
|
data/views/home.erb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
<p>
|
2
|
-
A simulated Puppet Enterprise infrastructure has been constructed on the
|
3
|
-
classroom server. Each student has an environment providing a sandboxed
|
4
|
-
container for Puppet code and configuration. The classroom server is also
|
5
|
-
running the unmodified Puppet Enterprise Console with an account for each
|
6
|
-
student.
|
7
|
-
</p>
|
8
|
-
|
9
|
-
<p>
|
10
|
-
Students have full <code>root</code> access on their container, meaning that all
|
11
|
-
Puppet commands and resources work as expected. Each container also exposes
|
12
|
-
port 80 as a high port proxied from the Master, meaning that students are able
|
13
|
-
to run a web server inside their sandbox environment. A link to this proxied
|
14
|
-
port is listed for each user on the <em>Users</em> tab.
|
15
|
-
</p>
|
16
|
-
|
17
|
-
<h3>Resources:</h3>
|
18
|
-
<ul>
|
19
|
-
<li><a href="http://<%= request.host %>:9090" target="_showoff">Course Material Presentation</a>
|
20
|
-
<ul>
|
21
|
-
<li>Follow along with the instructor's slides, or navigate it independently.</li>
|
22
|
-
</ul>
|
23
|
-
</li>
|
24
|
-
<li><a href="https://<%= request.host %>" target="_console">Puppet Enterprise Console</a>
|
25
|
-
<ul>
|
26
|
-
<li>Log into the PE Console using the credentials of the user account you created.</li>
|
27
|
-
</ul>
|
28
|
-
</li>
|
29
|
-
<% if settings.plugins.include? :Gitea -%>
|
30
|
-
<li><a href="http://<%= request.host %>:3000" target="_gitea">Git Repository Server</a>
|
31
|
-
<ul>
|
32
|
-
<li>Log into the Gitea server using the credentials of the user account you created.</li>
|
33
|
-
</ul>
|
34
|
-
</li>
|
35
|
-
<% end -%>
|
36
|
-
</ul>
|
37
|
-
|
38
|
-
<h3>Accessing your environment:</h3>
|
39
|
-
|
40
|
-
<ol>
|
41
|
-
<li>First create your account on the <em>Users</em> tab.</li>
|
42
|
-
<li>Log in to your sandbox following the directions on the <em>SSH Login</em> tab.</li>
|
43
|
-
<li>Log in to the <a href="https://<%= request.host %>" target="_console">Puppet Enterprise Console</a></li>
|
44
|
-
<ol>
|