ocp_registry 0.0.1.alpha

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.
Files changed (88) hide show
  1. data/.gitignore +25 -0
  2. data/Gemfile +17 -0
  3. data/Gemfile.lock +65 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/bin/ocp_registry +28 -0
  7. data/config/example-mysql.yml +40 -0
  8. data/config/example-sqlite.yml +33 -0
  9. data/lib/ocp_registry.rb +29 -0
  10. data/lib/ocp_registry/api_controller.rb +146 -0
  11. data/lib/ocp_registry/application_manager.rb +213 -0
  12. data/lib/ocp_registry/cloud_manager/mock.rb +5 -0
  13. data/lib/ocp_registry/cloud_manager/mock/mock.rb +191 -0
  14. data/lib/ocp_registry/cloud_manager/mock/model.rb +22 -0
  15. data/lib/ocp_registry/cloud_manager/openstack.rb +4 -0
  16. data/lib/ocp_registry/cloud_manager/openstack/cinder_helper.rb +27 -0
  17. data/lib/ocp_registry/cloud_manager/openstack/keystone_helper.rb +57 -0
  18. data/lib/ocp_registry/cloud_manager/openstack/nova_helper.rb +37 -0
  19. data/lib/ocp_registry/cloud_manager/openstack/openstack.rb +126 -0
  20. data/lib/ocp_registry/common.rb +54 -0
  21. data/lib/ocp_registry/config.rb +96 -0
  22. data/lib/ocp_registry/db/001_db_initialize.rb +16 -0
  23. data/lib/ocp_registry/error.rb +16 -0
  24. data/lib/ocp_registry/mail_client.rb +141 -0
  25. data/lib/ocp_registry/models.rb +7 -0
  26. data/lib/ocp_registry/models/registry_application.rb +10 -0
  27. data/lib/ocp_registry/runner.rb +47 -0
  28. data/lib/ocp_registry/version.rb +3 -0
  29. data/lib/ocp_registry/yaml_helper.rb +23 -0
  30. data/mail_template/approve_admin.erb +14 -0
  31. data/mail_template/approve_user.erb +22 -0
  32. data/mail_template/refuse_admin.erb +16 -0
  33. data/mail_template/refuse_user.erb +17 -0
  34. data/mail_template/request_admin.erb +15 -0
  35. data/mail_template/request_user.erb +16 -0
  36. data/ocp_registry.gemspec +34 -0
  37. data/public/bootstrap/css/bootstrap-responsive.css +1109 -0
  38. data/public/bootstrap/css/bootstrap-responsive.min.css +9 -0
  39. data/public/bootstrap/css/bootstrap.css +6167 -0
  40. data/public/bootstrap/css/bootstrap.min.css +9 -0
  41. data/public/bootstrap/img/glyphicons-halflings-white.png +0 -0
  42. data/public/bootstrap/img/glyphicons-halflings.png +0 -0
  43. data/public/bootstrap/js/bootstrap.js +2280 -0
  44. data/public/bootstrap/js/bootstrap.min.js +6 -0
  45. data/public/common.css +104 -0
  46. data/public/favicon.ico +0 -0
  47. data/public/images/loading.gif +0 -0
  48. data/public/jquery-1.10.2.min.js +6 -0
  49. data/public/jquery-1.10.2.min.map +1 -0
  50. data/public/jquery.json-2.4.min.js +23 -0
  51. data/public/noty/.gitignore +8 -0
  52. data/public/noty/LICENSE.txt +20 -0
  53. data/public/noty/README.markdown +22 -0
  54. data/public/noty/demo/allLayouts.html +91 -0
  55. data/public/noty/demo/allTypes.html +86 -0
  56. data/public/noty/demo/api.html +103 -0
  57. data/public/noty/demo/buttons.css +320 -0
  58. data/public/noty/demo/consumingAlert.html +78 -0
  59. data/public/noty/demo/customContainer.html +90 -0
  60. data/public/noty/demo/index.html +66 -0
  61. data/public/noty/demo/jquery-1.7.2.min.js +4 -0
  62. data/public/noty/demo/usingMaxVisible.html +104 -0
  63. data/public/noty/demo/usingWithButtons.html +104 -0
  64. data/public/noty/demo/usingWithButtons2.html +98 -0
  65. data/public/noty/demo/usingWithModal.html +87 -0
  66. data/public/noty/demo/usingWithOldOptions.html +110 -0
  67. data/public/noty/js/jquery.noty.js +547 -0
  68. data/public/noty/js/layouts/bottom.js +34 -0
  69. data/public/noty/js/layouts/bottomCenter.js +41 -0
  70. data/public/noty/js/layouts/bottomLeft.js +43 -0
  71. data/public/noty/js/layouts/bottomRight.js +43 -0
  72. data/public/noty/js/layouts/center.js +56 -0
  73. data/public/noty/js/layouts/centerLeft.js +61 -0
  74. data/public/noty/js/layouts/centerRight.js +61 -0
  75. data/public/noty/js/layouts/inline.js +31 -0
  76. data/public/noty/js/layouts/top.js +34 -0
  77. data/public/noty/js/layouts/topCenter.js +41 -0
  78. data/public/noty/js/layouts/topLeft.js +43 -0
  79. data/public/noty/js/layouts/topRight.js +43 -0
  80. data/public/noty/js/promise.js +432 -0
  81. data/public/noty/js/themes/default.js +156 -0
  82. data/views/apply.erb +134 -0
  83. data/views/base.erb +25 -0
  84. data/views/list.erb +41 -0
  85. data/views/review.erb +141 -0
  86. data/views/show.erb +96 -0
  87. data/views/view.erb +7 -0
  88. metadata +294 -0
@@ -0,0 +1,213 @@
1
+
2
+ module Ocp::Registry
3
+
4
+ class ApplicationManager
5
+
6
+ def initialize(cloud_manager,mail_manager)
7
+ @cloud_manager = cloud_manager
8
+ @mail_manager = mail_manager
9
+ @logger = Ocp::Registry.logger
10
+ end
11
+
12
+ def list(email=nil)
13
+ if email
14
+ results = Ocp::Registry::Models::RegistryApplication.reverse_order(:created_at).where(:email => email)
15
+ else
16
+ results = Ocp::Registry::Models::RegistryApplication.reverse_order(:created_at).all
17
+ end
18
+
19
+ results
20
+ end
21
+
22
+ def show(app_id)
23
+ app_info = get_application(app_id)
24
+ return {:status => "error", :message => "Application with id - [#{app_id}] is not existed"} if app_info.nil?
25
+ app_info
26
+ end
27
+
28
+ def default
29
+ @default ||= {
30
+ :email => "" ,
31
+ :project => "" ,
32
+ :description => "" ,
33
+ :settings => Yajl::Encoder.encode(@cloud_manager.default_quota)
34
+ }
35
+ end
36
+
37
+ def approve(app_id)
38
+ app_info = get_application(app_id)
39
+
40
+ return {:status => "error", :message => "Application with id - [#{app_id}] is not existed"} if app_info.nil?
41
+
42
+ return {:status => "error", :message => "Application [#{app_info.project}] - [#{app_id}] has been #{app_info.state}"} unless app_info.state == 'PENDING'
43
+
44
+ unless existed_tenant?(app_info.project, :find_local => false) then
45
+ # create project tenant and user
46
+ tenant = @cloud_manager.create_tenant(app_info.project, app_info.description)
47
+
48
+ @logger.info("Project [#{tenant.name}] - [#{tenant.id}] has been created with detailed json - #{tenant.to_json}")
49
+
50
+ username = Ocp::Registry::Common.parse_email(app_info.email)[:name]
51
+
52
+ user = @cloud_manager.find_user_by_name(username)
53
+
54
+ if user.nil?
55
+ password = Ocp::Registry::Common.gen_password
56
+ user = @cloud_manager.create_user(username, tenant.id, password, app_info.email)
57
+ @logger.info("User [#{user.name}] - [#{user.id}] has been created with detailed json - #{user.to_json}")
58
+ else
59
+ password = "<your-password-in-other-project>"
60
+ @logger.info("Using existed User [#{user.name}] - [#{user.id}] with detailed json - #{user.to_json}")
61
+ end
62
+
63
+ role = @cloud_manager.default_role
64
+
65
+ @cloud_manager.tenant_add_user_with_role(tenant, user.id, role.id)
66
+
67
+ @logger.info("User [#{user.name}] - [#{user.id}] has been added into project [#{tenant.name}] - [#{tenant.id}] as [#{role.name}] - [#{role.id}]")
68
+
69
+ #assign quota to project
70
+
71
+ settings = @cloud_manager.set_tenant_quota(tenant.id, Yajl.load(app_info.settings))
72
+
73
+ Ocp::Registry::Models::RegistryApplication.where(:id => app_id)
74
+ .update(:state => 'APPROVED',
75
+ :updated_at => Time.now.utc.to_s,
76
+ :settings => Yajl::Encoder.encode(settings) )
77
+ app_info = get_application(app_id)
78
+ if @mail_manager
79
+ admin_msg = {
80
+ :app_info => app_info ,
81
+ :application_link => gen_app_uri(app_id, :review => true) ,
82
+ :applications_link => gen_app_uri
83
+ }
84
+ mail = prepare_mail_properties(:approve_admin, @mail_manager.admin_emails, admin_msg)
85
+ @mail_manager.send_mail(mail)
86
+ user_msg = {
87
+ :app_info => app_info ,
88
+ :application_link => gen_app_uri(app_id) ,
89
+ :applications_link => gen_app_uri(nil, :email => app_info.email) ,
90
+ :login => Ocp::Registry.cloud_login_url ,
91
+ :username => username ,
92
+ :password => password
93
+ }
94
+ mail = prepare_mail_properties(:approve_user, app_info.email, user_msg)
95
+ @mail_manager.send_mail(mail)
96
+ end
97
+ app_info
98
+ else
99
+ @logger.info("Project [#{app_info.project}] name has been used during request time")
100
+ refuse(app_info.id,"Project Name [#{app_info.project}] has been used during request time")
101
+ end
102
+
103
+ end
104
+
105
+ def refuse(app_id,comments)
106
+ app_info = get_application(app_id)
107
+ return {:status => "error", :message => "Application with id - [#{app_id}] is not existed"} if app_info.nil?
108
+ return {:status => "error", :message => "Application [#{app_info.project}] - #{app_id} has been #{app_info.state}"} unless app_info.state == 'PENDING'
109
+
110
+ comments ||= "no comments"
111
+ Ocp::Registry::Models::RegistryApplication.where(:id => app_id)
112
+ .update(:state => 'REFUSED',
113
+ :updated_at => Time.now.utc.to_s,
114
+ :comments => comments)
115
+ app_info = get_application(app_id)
116
+
117
+ if @mail_manager
118
+ admin_msg = {
119
+ :app_info => app_info ,
120
+ :application_link => gen_app_uri(app_id, :review => true) ,
121
+ :applications_link => gen_app_uri
122
+ }
123
+ mail = prepare_mail_properties(:refuse_admin, @mail_manager.admin_emails, admin_msg)
124
+ @mail_manager.send_mail(mail)
125
+ user_msg = {
126
+ :app_info => app_info ,
127
+ :application_link => gen_app_uri(app_id) ,
128
+ :applications_link => gen_app_uri(nil, :email => app_info.email)
129
+ }
130
+ mail = prepare_mail_properties(:refuse_user, app_info.email, user_msg)
131
+ @mail_manager.send_mail(mail)
132
+ end
133
+ app_info
134
+ end
135
+
136
+ def create(app_info)
137
+ if existed_tenant?(app_info['project'])
138
+ {:status => "error", :message => "Project name [#{app_info['project']}] has been used"}
139
+ else
140
+ result = Ocp::Registry::Models::RegistryApplication.create(app_info)
141
+ if @mail_manager
142
+ admin_msg = {
143
+ :app_info => result ,
144
+ :application_link => gen_app_uri(result.id, :review => true) ,
145
+ :applications_link => gen_app_uri
146
+ }
147
+ mail = prepare_mail_properties(:request_admin, @mail_manager.admin_emails, admin_msg)
148
+ @mail_manager.send_mail(mail)
149
+ user_msg = {
150
+ :app_info => result ,
151
+ :application_link => gen_app_uri(result.id) ,
152
+ :applications_link => gen_app_uri(nil, :email => result.email)
153
+ }
154
+ mail = prepare_mail_properties(:request_user, result.email, user_msg)
155
+ @mail_manager.send_mail(mail)
156
+ end
157
+ result
158
+ end
159
+ end
160
+
161
+ def existed_tenant?(tenant, find_local = true)
162
+ if find_local
163
+ local_existed = Ocp::Registry::Models::RegistryApplication.where(:project => tenant, :state => 'APPROVED')
164
+ .count == 0? false : true
165
+ return true if local_existed
166
+ end
167
+ remote_existed = @cloud_manager.get_tenant_by_name(tenant)? true : false
168
+ if remote_existed
169
+ return true
170
+ else
171
+ return false
172
+ end
173
+ end
174
+
175
+ private
176
+
177
+ def get_application(app_id)
178
+ Ocp::Registry::Models::RegistryApplication[:id => app_id]
179
+ end
180
+
181
+ def prepare_mail_properties(template, to, msg = {})
182
+ {
183
+ :to => to ,
184
+ :template => template.to_s ,
185
+ :msg => msg
186
+ }
187
+ end
188
+
189
+ def gen_app_uri(app_id = nil, querys = nil)
190
+ host = URI::escape(Ocp::Registry.base_url)
191
+ port = Ocp::Registry.http_port
192
+ path = "/v1/applications"
193
+ if app_id
194
+ path += URI::escape("/#{app_id}")
195
+ end
196
+ query = nil
197
+ if(querys && querys.is_a?(Hash))
198
+ querys.each do |key, value|
199
+ if query.nil?
200
+ query = "#{key.to_s}=#{value}"
201
+ else
202
+ query += "&"
203
+ query += "#{key.to_s}=#{value}"
204
+ end
205
+ end
206
+ end
207
+
208
+ uri = URI::HTTP.build(:host => host, :port => port, :path => path, :query => query).to_s
209
+ end
210
+
211
+ end
212
+
213
+ end
@@ -0,0 +1,5 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+ $:.unshift(File.dirname(__FILE__))
3
+
4
+ require "mock/model"
5
+ require 'mock/mock'
@@ -0,0 +1,191 @@
1
+ module Ocp::Registry
2
+ class CloudManager
3
+
4
+ class Mock < CloudManager
5
+ def initialize(cloud_config)
6
+ validate_options(cloud_config)
7
+
8
+ @logger = Ocp::Registry.logger
9
+
10
+ @mock_properties = cloud_config["mock"]
11
+
12
+ unless @mock_properties["auth_url"].match(/\/tokens$/)
13
+ @mock_properties["auth_url"] = @mock_properties["auth_url"] + "/tokens"
14
+ end
15
+
16
+ @mock_options = {
17
+ :provider => "mock",
18
+ :mock_auth_url => @mock_properties["auth_url"],
19
+ :mock_username => @mock_properties["username"],
20
+ :mock_api_key => @mock_properties["api_key"],
21
+ :mock_tenant => @mock_properties["tenant"],
22
+ :mock_endpoint_type => @mock_properties["endpoint_type"]
23
+ }
24
+ @default_role_name = cloud_config["default_role"]
25
+ end
26
+
27
+ def validate_options(cloud_config)
28
+ unless cloud_config.has_key?("mock") &&
29
+ cloud_config["mock"].is_a?(Hash) &&
30
+ cloud_config["mock"]["auth_url"] &&
31
+ cloud_config["mock"]["username"] &&
32
+ cloud_config["mock"]["api_key"] &&
33
+ cloud_config["mock"]["tenant"] &&
34
+ cloud_config["default_role"]
35
+ raise ConfigError, "Invalid mock configuration parameters"
36
+ end
37
+ end
38
+
39
+ def default_compute_quota
40
+ {
41
+ "injected_file_content_bytes"=>10240,
42
+ "metadata_items"=>128,
43
+ "ram"=>51200,
44
+ "floating_ips"=>10,
45
+ "key_pairs"=>100,
46
+ "id"=>"defaults",
47
+ "instances"=>10,
48
+ "security_group_rules"=>20,
49
+ "injected_files"=>5,
50
+ "cores"=>20,
51
+ "fixed_ips"=>-1,
52
+ "injected_file_path_bytes"=>255,
53
+ "security_groups"=>10
54
+ }
55
+ end
56
+
57
+ def default_volume_quota
58
+ {
59
+ "gigabytes"=>1000,
60
+ "volumes"=>10,
61
+ "id"=>"defaults",
62
+ "snapshots"=>10
63
+ }
64
+ end
65
+
66
+ def default_quota
67
+ return @default_quota if @default_quota
68
+ compute_quota = default_compute_quota
69
+ volume_quota = default_volume_quota
70
+ @default_quota = compute_quota.merge (volume_quota)
71
+ cloud_error "Default Quota is not found" unless @default_quota
72
+ @default_quota
73
+ end
74
+
75
+ def get_role_by_name(name)
76
+ role = {
77
+ :id => "08bc68483a804ee59f4290256a8003c6",
78
+ :name => name
79
+ }
80
+ Model.new role
81
+ end
82
+
83
+ def default_role
84
+ return @default_role if @default_role
85
+ @default_role ||= get_role_by_name(@default_role_name)
86
+ cloud_error "Default Role [#{cloud_config["default_role"]}] is not found" unless @default_role
87
+ @logger.info("Default Role #{@default_role.name} - #{@default_role.id}")
88
+ @default_role
89
+ end
90
+
91
+ def set_tenant_quota(tenant_id, settings={})
92
+ result = nil
93
+ compute_quota = set_compute_quota(tenant_id, settings)
94
+ volume_quota = set_volume_quota(tenant_id, settings)
95
+ result = compute_quota.merge (volume_quota) if (compute_quota && volume_quota)
96
+ cloud_error "Quota for #{tenant_id} has not been set" unless result
97
+ result
98
+ end
99
+
100
+
101
+ def cloud_error(message, exception = nil)
102
+ @logger.error(message) if @logger
103
+ @logger.error(exception) if @logger && exception
104
+ raise Ocp::Registry::CloudError, message
105
+ end
106
+
107
+ CINDER_QUOTA_FIELDS = ["volumes", "snapshots", "gigabytes"]
108
+
109
+
110
+ def set_volume_quota(tenant_id, hash)
111
+ settings = Ocp::Registry::Common.hash_filter(hash, CINDER_QUOTA_FIELDS)
112
+ {
113
+ "gigabytes"=>1000,
114
+ "volumes"=>10,
115
+ "id"=>"defaults",
116
+ "snapshots"=>10
117
+ }.merge settings
118
+ end
119
+
120
+ def create_tenant(name, description, enabled = true)
121
+ tenant = {
122
+ :name => "your project name",
123
+ :description => "your project description",
124
+ :enabled => true,
125
+ :id => "1bb0fed1c2df4b5faa19e7700c049e35"
126
+ }
127
+ Model.new tenant
128
+ end
129
+
130
+ def create_user(name, tenant_id, password, email = '')
131
+ user = {
132
+ :email => email,
133
+ :enabled => true,
134
+ :name => name,
135
+ :tenant_id => tenant_id,
136
+ :password => password
137
+ }
138
+ Model.new user
139
+ end
140
+
141
+ def get_tenant_by_name(name)
142
+ nil
143
+ end
144
+
145
+ def tenant_add_user_with_role(tenant, user_id, role_id)
146
+ true
147
+ end
148
+
149
+ def find_user_by_name(name)
150
+ user = {
151
+ :email => "#{name}@email.com",
152
+ :enabled => true,
153
+ :name => name,
154
+ :tenant_id => "1bb0fed1c2df4b5faa19e7700c049e35",
155
+ :password => "passwordxxxxx"
156
+ }
157
+ Model.new user
158
+ end
159
+
160
+ NOVA_QUOTA_FIELDS = ["metadata_items",
161
+ "cores",
162
+ "instances",
163
+ "injected_files",
164
+ "injected_file_content_bytes",
165
+ "ram",
166
+ "floating_ips",
167
+ "fixed_ips",
168
+ "security_groups",
169
+ "security_group_rules"]
170
+
171
+ def set_compute_quota(tenant_id, hash)
172
+ settings = Ocp::Registry::Common.hash_filter(hash, NOVA_QUOTA_FIELDS)
173
+ {
174
+ "injected_file_content_bytes"=>10240,
175
+ "metadata_items"=>128, "ram"=>51200,
176
+ "floating_ips"=>10,
177
+ "key_pairs"=>100,
178
+ "id"=>"defaults",
179
+ "instances"=>10,
180
+ "security_group_rules"=>20,
181
+ "injected_files"=>5,
182
+ "cores"=>20,
183
+ "fixed_ips"=>-1,
184
+ "injected_file_path_bytes"=>255,
185
+ "security_groups"=>10
186
+ }.merge settings
187
+ end
188
+
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,22 @@
1
+ module Ocp::Registry
2
+ class CloudManager
3
+
4
+ class Mock < CloudManager
5
+ class Model
6
+ def initialize(properties)
7
+ if properties.is_a? (Hash)
8
+ @properties = properties
9
+ end
10
+ end
11
+
12
+ def method_missing(method, *args)
13
+ return @properties[method.to_sym]
14
+ end
15
+
16
+ def to_json
17
+ Yajl::Encoder.encode(@properties)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,4 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+ $:.unshift(File.dirname(__FILE__))
3
+
4
+ require 'openstack/openstack'
@@ -0,0 +1,27 @@
1
+ module Ocp::Registry
2
+
3
+ class CloudManager
4
+
5
+ class Openstack
6
+
7
+ module CinderHelper
8
+ CINDER_QUOTA_FIELDS = ["volumes", "snapshots", "gigabytes"]
9
+
10
+ def default_volume_quota
11
+ with_openstack { volume.get_quota_defaults(nil).body["quota_set"] }
12
+ end
13
+
14
+ def set_volume_quota(tenant_id, hash)
15
+ with_openstack do
16
+ settings = Ocp::Registry::Common.hash_filter(hash, CINDER_QUOTA_FIELDS)
17
+ volume.update_quota(tenant_id, settings).body["quota_set"]
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+ end