puppetfactory 0.5.9 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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>
|