ocp_registry 0.0.1.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +25 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +65 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/bin/ocp_registry +28 -0
- data/config/example-mysql.yml +40 -0
- data/config/example-sqlite.yml +33 -0
- data/lib/ocp_registry.rb +29 -0
- data/lib/ocp_registry/api_controller.rb +146 -0
- data/lib/ocp_registry/application_manager.rb +213 -0
- data/lib/ocp_registry/cloud_manager/mock.rb +5 -0
- data/lib/ocp_registry/cloud_manager/mock/mock.rb +191 -0
- data/lib/ocp_registry/cloud_manager/mock/model.rb +22 -0
- data/lib/ocp_registry/cloud_manager/openstack.rb +4 -0
- data/lib/ocp_registry/cloud_manager/openstack/cinder_helper.rb +27 -0
- data/lib/ocp_registry/cloud_manager/openstack/keystone_helper.rb +57 -0
- data/lib/ocp_registry/cloud_manager/openstack/nova_helper.rb +37 -0
- data/lib/ocp_registry/cloud_manager/openstack/openstack.rb +126 -0
- data/lib/ocp_registry/common.rb +54 -0
- data/lib/ocp_registry/config.rb +96 -0
- data/lib/ocp_registry/db/001_db_initialize.rb +16 -0
- data/lib/ocp_registry/error.rb +16 -0
- data/lib/ocp_registry/mail_client.rb +141 -0
- data/lib/ocp_registry/models.rb +7 -0
- data/lib/ocp_registry/models/registry_application.rb +10 -0
- data/lib/ocp_registry/runner.rb +47 -0
- data/lib/ocp_registry/version.rb +3 -0
- data/lib/ocp_registry/yaml_helper.rb +23 -0
- data/mail_template/approve_admin.erb +14 -0
- data/mail_template/approve_user.erb +22 -0
- data/mail_template/refuse_admin.erb +16 -0
- data/mail_template/refuse_user.erb +17 -0
- data/mail_template/request_admin.erb +15 -0
- data/mail_template/request_user.erb +16 -0
- data/ocp_registry.gemspec +34 -0
- data/public/bootstrap/css/bootstrap-responsive.css +1109 -0
- data/public/bootstrap/css/bootstrap-responsive.min.css +9 -0
- data/public/bootstrap/css/bootstrap.css +6167 -0
- data/public/bootstrap/css/bootstrap.min.css +9 -0
- data/public/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/public/bootstrap/img/glyphicons-halflings.png +0 -0
- data/public/bootstrap/js/bootstrap.js +2280 -0
- data/public/bootstrap/js/bootstrap.min.js +6 -0
- data/public/common.css +104 -0
- data/public/favicon.ico +0 -0
- data/public/images/loading.gif +0 -0
- data/public/jquery-1.10.2.min.js +6 -0
- data/public/jquery-1.10.2.min.map +1 -0
- data/public/jquery.json-2.4.min.js +23 -0
- data/public/noty/.gitignore +8 -0
- data/public/noty/LICENSE.txt +20 -0
- data/public/noty/README.markdown +22 -0
- data/public/noty/demo/allLayouts.html +91 -0
- data/public/noty/demo/allTypes.html +86 -0
- data/public/noty/demo/api.html +103 -0
- data/public/noty/demo/buttons.css +320 -0
- data/public/noty/demo/consumingAlert.html +78 -0
- data/public/noty/demo/customContainer.html +90 -0
- data/public/noty/demo/index.html +66 -0
- data/public/noty/demo/jquery-1.7.2.min.js +4 -0
- data/public/noty/demo/usingMaxVisible.html +104 -0
- data/public/noty/demo/usingWithButtons.html +104 -0
- data/public/noty/demo/usingWithButtons2.html +98 -0
- data/public/noty/demo/usingWithModal.html +87 -0
- data/public/noty/demo/usingWithOldOptions.html +110 -0
- data/public/noty/js/jquery.noty.js +547 -0
- data/public/noty/js/layouts/bottom.js +34 -0
- data/public/noty/js/layouts/bottomCenter.js +41 -0
- data/public/noty/js/layouts/bottomLeft.js +43 -0
- data/public/noty/js/layouts/bottomRight.js +43 -0
- data/public/noty/js/layouts/center.js +56 -0
- data/public/noty/js/layouts/centerLeft.js +61 -0
- data/public/noty/js/layouts/centerRight.js +61 -0
- data/public/noty/js/layouts/inline.js +31 -0
- data/public/noty/js/layouts/top.js +34 -0
- data/public/noty/js/layouts/topCenter.js +41 -0
- data/public/noty/js/layouts/topLeft.js +43 -0
- data/public/noty/js/layouts/topRight.js +43 -0
- data/public/noty/js/promise.js +432 -0
- data/public/noty/js/themes/default.js +156 -0
- data/views/apply.erb +134 -0
- data/views/base.erb +25 -0
- data/views/list.erb +41 -0
- data/views/review.erb +141 -0
- data/views/show.erb +96 -0
- data/views/view.erb +7 -0
- metadata +294 -0
@@ -0,0 +1,156 @@
|
|
1
|
+
;(function($) {
|
2
|
+
|
3
|
+
$.noty.themes.defaultTheme = {
|
4
|
+
name: 'defaultTheme',
|
5
|
+
helpers: {
|
6
|
+
borderFix: function() {
|
7
|
+
if (this.options.dismissQueue) {
|
8
|
+
var selector = this.options.layout.container.selector + ' ' + this.options.layout.parent.selector;
|
9
|
+
switch (this.options.layout.name) {
|
10
|
+
case 'top':
|
11
|
+
$(selector).css({borderRadius: '0px 0px 0px 0px'});
|
12
|
+
$(selector).last().css({borderRadius: '0px 0px 5px 5px'}); break;
|
13
|
+
case 'topCenter': case 'topLeft': case 'topRight':
|
14
|
+
case 'bottomCenter': case 'bottomLeft': case 'bottomRight':
|
15
|
+
case 'center': case 'centerLeft': case 'centerRight': case 'inline':
|
16
|
+
$(selector).css({borderRadius: '0px 0px 0px 0px'});
|
17
|
+
$(selector).first().css({'border-top-left-radius': '5px', 'border-top-right-radius': '5px'});
|
18
|
+
$(selector).last().css({'border-bottom-left-radius': '5px', 'border-bottom-right-radius': '5px'}); break;
|
19
|
+
case 'bottom':
|
20
|
+
$(selector).css({borderRadius: '0px 0px 0px 0px'});
|
21
|
+
$(selector).first().css({borderRadius: '5px 5px 0px 0px'}); break;
|
22
|
+
default: break;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
},
|
27
|
+
modal: {
|
28
|
+
css: {
|
29
|
+
position: 'fixed',
|
30
|
+
width: '100%',
|
31
|
+
height: '100%',
|
32
|
+
backgroundColor: '#000',
|
33
|
+
zIndex: 10000,
|
34
|
+
opacity: 0.6,
|
35
|
+
display: 'none',
|
36
|
+
left: 0,
|
37
|
+
top: 0
|
38
|
+
}
|
39
|
+
},
|
40
|
+
style: function() {
|
41
|
+
|
42
|
+
this.$bar.css({
|
43
|
+
overflow: 'hidden',
|
44
|
+
background: "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAoCAYAAAAPOoFWAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPZJREFUeNq81tsOgjAMANB2ov7/7ypaN7IlIwi9rGuT8QSc9EIDAsAznxvY4pXPKr05RUE5MEVB+TyWfCEl9LZApYopCmo9C4FKSMtYoI8Bwv79aQJU4l6hXXCZrQbokJEksxHo9KMOgc6w1atHXM8K9DVC7FQnJ0i8iK3QooGgbnyKgMDygBWyYFZoqx4qS27KqLZJjA1D0jK6QJcYEQEiWv9PGkTsbqxQ8oT+ZtZB6AkdsJnQDnMoHXHLGKOgDYuCWmYhEERCI5gaamW0bnHdA3k2ltlIN+2qKRyCND0bhqSYCyTB3CAOc4WusBEIpkeBuPgJMAAX8Hs1NfqHRgAAAABJRU5ErkJggg==') repeat-x scroll left top #fff"
|
45
|
+
});
|
46
|
+
|
47
|
+
this.$message.css({
|
48
|
+
fontSize: '13px',
|
49
|
+
lineHeight: '16px',
|
50
|
+
textAlign: 'center',
|
51
|
+
padding: '8px 10px 9px',
|
52
|
+
width: 'auto',
|
53
|
+
position: 'relative'
|
54
|
+
});
|
55
|
+
|
56
|
+
this.$closeButton.css({
|
57
|
+
position: 'absolute',
|
58
|
+
top: 4, right: 4,
|
59
|
+
width: 10, height: 10,
|
60
|
+
background: "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAATpJREFUeNoszrFqVFEUheG19zlz7sQ7ijMQBAvfYBqbpJCoZSAQbOwEE1IHGytbLQUJ8SUktW8gCCFJMSGSNxCmFBJO7j5rpXD6n5/P5vM53H3b3T9LOiB5AQDuDjM7BnA7DMPHDGBH0nuSzwHsRcRVRNRSysuU0i6AOwA/02w2+9Fae00SEbEh6SGAR5K+k3zWWptKepCm0+kpyRoRGyRBcpPkDsn1iEBr7drdP2VJZyQXERGSPpiZAViTBACXKaV9kqd5uVzCzO5KKb/d/UZSDwD/eyxqree1VqSu6zKAF2Z2RPJJaw0rAkjOJT0m+SuT/AbgDcmnkmBmfwAsJL1dXQ8lWY6IGwB1ZbrOOb8zs8thGP4COFwx/mE8Ho9Go9ErMzvJOW/1fY/JZIJSypqZfXX3L13X9fcDAKJct1sx3OiuAAAAAElFTkSuQmCC)",
|
61
|
+
display: 'none',
|
62
|
+
cursor: 'pointer'
|
63
|
+
});
|
64
|
+
|
65
|
+
this.$buttons.css({
|
66
|
+
padding: 5,
|
67
|
+
textAlign: 'right',
|
68
|
+
borderTop: '1px solid #ccc',
|
69
|
+
backgroundColor: '#fff'
|
70
|
+
});
|
71
|
+
|
72
|
+
this.$buttons.find('button').css({
|
73
|
+
marginLeft: 5
|
74
|
+
});
|
75
|
+
|
76
|
+
this.$buttons.find('button:first').css({
|
77
|
+
marginLeft: 0
|
78
|
+
});
|
79
|
+
|
80
|
+
this.$bar.bind({
|
81
|
+
mouseenter: function() { $(this).find('.noty_close').stop().fadeTo('normal',1); },
|
82
|
+
mouseleave: function() { $(this).find('.noty_close').stop().fadeTo('normal',0); }
|
83
|
+
});
|
84
|
+
|
85
|
+
switch (this.options.layout.name) {
|
86
|
+
case 'top':
|
87
|
+
this.$bar.css({
|
88
|
+
borderRadius: '0px 0px 5px 5px',
|
89
|
+
borderBottom: '2px solid #eee',
|
90
|
+
borderLeft: '2px solid #eee',
|
91
|
+
borderRight: '2px solid #eee',
|
92
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)"
|
93
|
+
});
|
94
|
+
break;
|
95
|
+
case 'topCenter': case 'center': case 'bottomCenter': case 'inline':
|
96
|
+
this.$bar.css({
|
97
|
+
borderRadius: '5px',
|
98
|
+
border: '1px solid #eee',
|
99
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)"
|
100
|
+
});
|
101
|
+
this.$message.css({fontSize: '13px', textAlign: 'center'});
|
102
|
+
break;
|
103
|
+
case 'topLeft': case 'topRight':
|
104
|
+
case 'bottomLeft': case 'bottomRight':
|
105
|
+
case 'centerLeft': case 'centerRight':
|
106
|
+
this.$bar.css({
|
107
|
+
borderRadius: '5px',
|
108
|
+
border: '1px solid #eee',
|
109
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)"
|
110
|
+
});
|
111
|
+
this.$message.css({fontSize: '13px', textAlign: 'left'});
|
112
|
+
break;
|
113
|
+
case 'bottom':
|
114
|
+
this.$bar.css({
|
115
|
+
borderRadius: '5px 5px 0px 0px',
|
116
|
+
borderTop: '2px solid #eee',
|
117
|
+
borderLeft: '2px solid #eee',
|
118
|
+
borderRight: '2px solid #eee',
|
119
|
+
boxShadow: "0 -2px 4px rgba(0, 0, 0, 0.1)"
|
120
|
+
});
|
121
|
+
break;
|
122
|
+
default:
|
123
|
+
this.$bar.css({
|
124
|
+
border: '2px solid #eee',
|
125
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)"
|
126
|
+
});
|
127
|
+
break;
|
128
|
+
}
|
129
|
+
|
130
|
+
switch (this.options.type) {
|
131
|
+
case 'alert': case 'notification':
|
132
|
+
this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'}); break;
|
133
|
+
case 'warning':
|
134
|
+
this.$bar.css({backgroundColor: '#FFEAA8', borderColor: '#FFC237', color: '#826200'});
|
135
|
+
this.$buttons.css({borderTop: '1px solid #FFC237'}); break;
|
136
|
+
case 'error':
|
137
|
+
this.$bar.css({backgroundColor: 'red', borderColor: 'darkred', color: '#FFF'});
|
138
|
+
this.$message.css({fontWeight: 'bold'});
|
139
|
+
this.$buttons.css({borderTop: '1px solid darkred'}); break;
|
140
|
+
case 'information':
|
141
|
+
this.$bar.css({backgroundColor: '#57B7E2', borderColor: '#0B90C4', color: '#FFF'});
|
142
|
+
this.$buttons.css({borderTop: '1px solid #0B90C4'}); break;
|
143
|
+
case 'success':
|
144
|
+
this.$bar.css({backgroundColor: 'lightgreen', borderColor: '#50C24E', color: 'darkgreen'});
|
145
|
+
this.$buttons.css({borderTop: '1px solid #50C24E'});break;
|
146
|
+
default:
|
147
|
+
this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'}); break;
|
148
|
+
}
|
149
|
+
},
|
150
|
+
callback: {
|
151
|
+
onShow: function() { $.noty.themes.defaultTheme.helpers.borderFix.apply(this); },
|
152
|
+
onClose: function() { $.noty.themes.defaultTheme.helpers.borderFix.apply(this); }
|
153
|
+
}
|
154
|
+
};
|
155
|
+
|
156
|
+
})(jQuery);
|
data/views/apply.erb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
|
2
|
+
<div class="bordered optDialog">
|
3
|
+
<legend>Create Project</legend>
|
4
|
+
|
5
|
+
<%=erb :show, :locals => {:data=>data, :readonly=>false} %>
|
6
|
+
|
7
|
+
<div class="optAction" id="optAction">
|
8
|
+
<button id="optSubmit" type="button" class="btn btn-primary toRight"
|
9
|
+
data-loading-text="Loading ..."
|
10
|
+
data-complete-text="Completed!">
|
11
|
+
Submit</button>
|
12
|
+
<img class="loadingIcon toRight" id="optActionLoadingIcon" src="/images/loading.gif" alt="" />
|
13
|
+
<div class="clear"></div>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
</div>
|
17
|
+
|
18
|
+
|
19
|
+
<script type="text/javascript">
|
20
|
+
|
21
|
+
(function(){
|
22
|
+
|
23
|
+
$(document).ready(init);
|
24
|
+
|
25
|
+
function init(){
|
26
|
+
initOptSubmit();
|
27
|
+
}
|
28
|
+
|
29
|
+
function initOptSubmit(){
|
30
|
+
$('#optSubmit').click(function(){
|
31
|
+
$.noty.closeAll();
|
32
|
+
|
33
|
+
//check the data corrections
|
34
|
+
var ret=checkTenantFields();
|
35
|
+
if(!ret.ret){
|
36
|
+
var fieldNamesStr="";
|
37
|
+
$.each(ret.fields, function(i, v){
|
38
|
+
if(i>=ret.fields.length-1){
|
39
|
+
fieldNamesStr+=v;
|
40
|
+
}else{
|
41
|
+
fieldNamesStr+=v+" and ";
|
42
|
+
}
|
43
|
+
});
|
44
|
+
|
45
|
+
noty({text: "Field "+fieldNamesStr+" "+((ret.fields.length>1)?"are":"is")+" invalid.", type: 'error'});
|
46
|
+
return;
|
47
|
+
}
|
48
|
+
|
49
|
+
//do the submission
|
50
|
+
submitBtnToLoading();
|
51
|
+
var data=generateTenantRequest();
|
52
|
+
|
53
|
+
$.post('/v1/applications', data, 'json').done(function(data){
|
54
|
+
data = $.evalJSON(data);
|
55
|
+
if(data.status&&data.status=='error'){
|
56
|
+
//server returned error
|
57
|
+
noty({text: 'Failed to Submit Your Request: '+(data.message?data.message:'Unknown Error'), type:'error'});
|
58
|
+
submitBtnToReady();
|
59
|
+
}else{
|
60
|
+
noty({text: 'Successfully Submitted Your Request! You Can Close This Window Now.', type:'success'});
|
61
|
+
submitBtnToComplete();
|
62
|
+
}
|
63
|
+
}).fail(function(){
|
64
|
+
noty({text: 'Failed to Submit Your Request: Connection Error. You May Retry Later.', type:'error'});
|
65
|
+
submitBtnToReady();
|
66
|
+
});
|
67
|
+
|
68
|
+
});
|
69
|
+
}
|
70
|
+
|
71
|
+
function submitBtnToLoading(){
|
72
|
+
$('#optSubmit').button('loading');
|
73
|
+
$('#optSubmit').attr('disabled', 'true');
|
74
|
+
$('#optActionLoadingIcon').show();
|
75
|
+
}
|
76
|
+
|
77
|
+
function submitBtnToReady(){
|
78
|
+
$('#optSubmit').button('reset');
|
79
|
+
$('#optSubmit').removeAttr('disabled');
|
80
|
+
$('#optActionLoadingIcon').hide();
|
81
|
+
}
|
82
|
+
|
83
|
+
function submitBtnToComplete(){
|
84
|
+
//$('#optSubmit').button('complete'); //BUG here: I don't use this. Because this will cause the button to be enabled. I want it to keep disabled.
|
85
|
+
$('#optSubmit').text("Completed");
|
86
|
+
$('#optSubmit').attr('disabled', 'true');
|
87
|
+
$('#optActionLoadingIcon').hide();
|
88
|
+
}
|
89
|
+
|
90
|
+
function checkTenantFields(){
|
91
|
+
var project=$('#tenantInfo input[name=project]').val();
|
92
|
+
var email=$('#tenantInfo input[name=email]').val();
|
93
|
+
|
94
|
+
var result={ret:true, fields:[]};
|
95
|
+
|
96
|
+
if(!project||project.length<=0){
|
97
|
+
result.ret=false;
|
98
|
+
result.fields.push("project");
|
99
|
+
}
|
100
|
+
if(!email||email.length<=0){
|
101
|
+
result.ret=false;
|
102
|
+
result.fields.push("email");
|
103
|
+
}
|
104
|
+
|
105
|
+
return result;
|
106
|
+
}
|
107
|
+
|
108
|
+
function generateTenantRequest(){
|
109
|
+
var data={
|
110
|
+
project : $('#tenantInfo input[name=project]').val(),
|
111
|
+
description : $('#tenantInfo input[name=description]').val(),
|
112
|
+
email : $('#tenantInfo input[name=email]').val(),
|
113
|
+
settings :
|
114
|
+
{
|
115
|
+
metadata_items : $('#quota input[name=metadata_items]').val(),
|
116
|
+
cores : $('#quota input[name=cores]').val(),
|
117
|
+
instances : $('#quota input[name=instances]').val(),
|
118
|
+
injected_files : $('#quota input[name=injected_files]').val(),
|
119
|
+
injected_file_content_bytes : $('#quota input[name=injected_file_content_bytes]').val(),
|
120
|
+
volumes : $('#quota input[name=volumes]').val(),
|
121
|
+
gigabytes : $('#quota input[name=gigabytes]').val(),
|
122
|
+
ram : $('#quota input[name=ram]').val(),
|
123
|
+
floating_ips : $('#quota input[name=floating_ips]').val(),
|
124
|
+
fixed_ips : $('#quota input[name=floating_ips]').val(),
|
125
|
+
security_groups : $('#quota input[name=security_groups]').val(),
|
126
|
+
security_group_rules : $('#quota input[name=security_group_rules]').val()
|
127
|
+
}
|
128
|
+
};
|
129
|
+
return $.toJSON( data );
|
130
|
+
}
|
131
|
+
|
132
|
+
})();
|
133
|
+
|
134
|
+
</script>
|
data/views/base.erb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title></title>
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<!-- Bootstrap -->
|
7
|
+
<link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
|
8
|
+
<link rel="stylesheet" type="text/css" href="/common.css">
|
9
|
+
<script src="/jquery-1.10.2.min.js"></script>
|
10
|
+
<script src="/bootstrap/js/bootstrap.min.js"></script>
|
11
|
+
<script type="text/javascript" src="/noty/js/jquery.noty.js"></script>
|
12
|
+
<script type="text/javascript" src="/noty/js/layouts/top.js"></script>
|
13
|
+
<script type="text/javascript" src="/noty/js/layouts/topLeft.js"></script>
|
14
|
+
<script type="text/javascript" src="/noty/js/layouts/topRight.js"></script>
|
15
|
+
<script type="text/javascript" src="/noty/js/layouts/topCenter.js"></script>
|
16
|
+
<script type="text/javascript" src="/noty/js/themes/default.js"></script>
|
17
|
+
<script type="text/javascript" src="/jquery.json-2.4.min.js"></script>
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<div class="container">
|
21
|
+
<%=yield %>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
</body>
|
25
|
+
</html>
|
data/views/list.erb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
<div class="page-header">
|
2
|
+
<h1>Projects</h1>
|
3
|
+
</div>
|
4
|
+
<div class="table_wrapper">
|
5
|
+
<table class="table table-bordered table-striped datatable">
|
6
|
+
<thead>
|
7
|
+
<tr>
|
8
|
+
<th class="sortable normal_column">Name</th>
|
9
|
+
<th class="sortable normal_column">Description</th>
|
10
|
+
<th class="sortable normal_column">Project ID</th>
|
11
|
+
<th class="sortable normal_column">Status</th>
|
12
|
+
<th class="sortable normal_column">Requestor</th>
|
13
|
+
<th class="normal_column">Action</th>
|
14
|
+
</tr>
|
15
|
+
</thead>
|
16
|
+
<tbody>
|
17
|
+
<% data.each do |app| %>
|
18
|
+
<tr>
|
19
|
+
<td class="sortable normal_column"><%=app[:project]%></td>
|
20
|
+
<td class="sortable normal_column"><%=app[:description]%></td>
|
21
|
+
<td class="sortable normal_column"><%=app[:id]%></td>
|
22
|
+
<td class="status_up sortable normal_column"><%=app[:state]%></td>
|
23
|
+
<td class="sortable normal_column"><%=app[:email]%></td>
|
24
|
+
<td class="normal_column">
|
25
|
+
<% link = "/v1/applications/#{app[:id]}"
|
26
|
+
link += "?review=true" if mark && mark[:review] %>
|
27
|
+
<a href="<%=link%>" class="btn btn-small">View</a>
|
28
|
+
</td>
|
29
|
+
</tr>
|
30
|
+
<% end %>
|
31
|
+
</tbody>
|
32
|
+
<tfoot>
|
33
|
+
|
34
|
+
<tr>
|
35
|
+
<td colspan="6">
|
36
|
+
<span class="table_count">Displaying <%=data.size%> items</span>
|
37
|
+
</td>
|
38
|
+
</tr>
|
39
|
+
</tfoot>
|
40
|
+
</table>
|
41
|
+
</div>
|
data/views/review.erb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
|
2
|
+
<div class="bordered optDialog">
|
3
|
+
<legend>Review Project Request</legend>
|
4
|
+
|
5
|
+
<%=erb :show, :locals => {:data=>data, :readonly=>true} %>
|
6
|
+
|
7
|
+
<div class="optAction" id="optAction">
|
8
|
+
<button id="optAccept" type="button" class="btn btn-success toRight"
|
9
|
+
data-loading-text="Loading ...">
|
10
|
+
Accept
|
11
|
+
</button>
|
12
|
+
<button id="optReject" type="button" class="btn btn-warning toRight"
|
13
|
+
data-loading-text="Loading ...">
|
14
|
+
Reject
|
15
|
+
</button>
|
16
|
+
<img class="loadingIcon toRight" id="optActionLoadingIcon" src="/images/loading.gif" alt="" />
|
17
|
+
<button id="optBack" type="button" class="btn toRight">Back</button>
|
18
|
+
<div class="clear"></div>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<div id="rejectCommentDialog" class="bordered rejectCommentDialog modal hide" tabindex="-1" role="dialog" aria-labelledby="Rejection Comment" aria-hidden="true">
|
24
|
+
<legend>Comment</legend>
|
25
|
+
|
26
|
+
<textarea name="rejectCommentText" placeholder="Put your comment for rejection here ..."></textarea>
|
27
|
+
|
28
|
+
<div class="rejectCommentAction">
|
29
|
+
<button id="rejectCommentConfirm" type="button" class="btn btn-primary toRight">Confirm</button>
|
30
|
+
<button id="rejectCommentBack" type="button" class="btn toRight">Back</button>
|
31
|
+
<div class="clear"></div>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<script type="text/javascript">
|
36
|
+
|
37
|
+
$(document).ready(init);
|
38
|
+
|
39
|
+
function init(){
|
40
|
+
initOptActions();
|
41
|
+
initRejectCommentDialogActions();
|
42
|
+
}
|
43
|
+
|
44
|
+
function initOptActions(){
|
45
|
+
$('#optBack').hide();
|
46
|
+
$('#optBack').click(function(){
|
47
|
+
window.location='/v1/applications';
|
48
|
+
});
|
49
|
+
|
50
|
+
$('#optAccept').click(function(){
|
51
|
+
$.noty.closeAll();
|
52
|
+
handleActionClick('accept', null);
|
53
|
+
});
|
54
|
+
$('#optReject').click(function(){
|
55
|
+
$.noty.closeAll();
|
56
|
+
$('#rejectCommentDialog').modal();
|
57
|
+
});
|
58
|
+
}
|
59
|
+
|
60
|
+
function initRejectCommentDialogActions(){
|
61
|
+
|
62
|
+
$('#rejectCommentBack').click(function(){
|
63
|
+
$('#rejectCommentDialog').modal('hide');
|
64
|
+
});
|
65
|
+
|
66
|
+
$('#rejectCommentConfirm').click(function(){
|
67
|
+
$('#rejectCommentDialog').modal('hide');
|
68
|
+
|
69
|
+
var data={
|
70
|
+
comments: $('textarea[name=rejectCommentText]').val()
|
71
|
+
};
|
72
|
+
data=$.toJSON( data );
|
73
|
+
|
74
|
+
handleActionClick('reject', data);
|
75
|
+
|
76
|
+
});
|
77
|
+
|
78
|
+
}
|
79
|
+
|
80
|
+
function handleActionClick(which, dataToSend){
|
81
|
+
actionBtnToLoading(which);
|
82
|
+
var url='/v1/applications/'+'<%=data[:id]%>'+'/'+((which=="accept")?"approve":"refuse");
|
83
|
+
$.post(url, dataToSend, 'json').done(function(data){
|
84
|
+
data = $.evalJSON(data);
|
85
|
+
if(data.status&&data.status=='error'){
|
86
|
+
//server returned error
|
87
|
+
noty({text: 'Failed to Submit Your Decision: '+(data.message?data.message:'Unknown Error'), type:'error'});
|
88
|
+
actionBtnToReady();
|
89
|
+
}else{
|
90
|
+
noty({text: 'Successfully Submitted Your Decision!', type:'success'});
|
91
|
+
actionBtnToComplete(which);
|
92
|
+
}
|
93
|
+
}).fail(function(){
|
94
|
+
noty({text: 'Failed to Submit Your Decision: Connection Error. You May Retry Later.', type:'error'});
|
95
|
+
actionBtnToReady();
|
96
|
+
});
|
97
|
+
|
98
|
+
}
|
99
|
+
|
100
|
+
function actionBtnToLoading(which){
|
101
|
+
if(which=="accept"){
|
102
|
+
$('#optAccept').button("loading");
|
103
|
+
}else if(which=="reject"){
|
104
|
+
$('#optReject').button("loading");
|
105
|
+
}else{
|
106
|
+
throw "This statement should never be reached!"
|
107
|
+
}
|
108
|
+
|
109
|
+
$('#optAccept').attr('disabled', 'true');
|
110
|
+
$('#optReject').attr('disabled', 'true');
|
111
|
+
|
112
|
+
$('#optActionLoadingIcon').show();
|
113
|
+
}
|
114
|
+
|
115
|
+
function actionBtnToReady(){
|
116
|
+
$('#optAccept').button('reset');
|
117
|
+
$('#optReject').button('reset');
|
118
|
+
|
119
|
+
$('#optReject').removeAttr('disabled');
|
120
|
+
$('#optAccept').removeAttr('disabled');
|
121
|
+
|
122
|
+
$('#optActionLoadingIcon').hide();
|
123
|
+
}
|
124
|
+
|
125
|
+
function actionBtnToComplete(which){
|
126
|
+
$('#optAccept').attr('disabled', 'true');
|
127
|
+
$('#optReject').attr('disabled', 'true');
|
128
|
+
$('#optActionLoadingIcon').hide();
|
129
|
+
|
130
|
+
if(which=="accept"){
|
131
|
+
$('#optAccept').text("Completed");
|
132
|
+
}else if(which=="reject"){
|
133
|
+
$('#optReject').text("Complete");
|
134
|
+
}else{
|
135
|
+
throw "This statement should never be reached!"
|
136
|
+
}
|
137
|
+
|
138
|
+
$('#optBack').show();
|
139
|
+
}
|
140
|
+
|
141
|
+
</script>
|