superhosting 0.0.1 → 0.0.2

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 (248) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +1 -0
  3. data/.travis.yml +13 -0
  4. data/Gemfile.lock +43 -7
  5. data/LICENSE.txt +4 -1
  6. data/Vagrantfile +6 -3
  7. data/bin/sx +6 -2
  8. data/bootstrap/etc/sx/default_model +1 -0
  9. data/bootstrap/etc/sx/models/base/container/docker/command +1 -0
  10. data/bootstrap/etc/sx/models/base/container/docker/user.erb +1 -0
  11. data/bootstrap/etc/sx/models/base/container/docker/volume.erb +2 -0
  12. data/bootstrap/etc/sx/models/bitrix_l/inherit +3 -0
  13. data/bootstrap/etc/sx/models/bitrix_m/inherit +3 -0
  14. data/bootstrap/etc/sx/models/bitrix_xl/inherit +3 -0
  15. data/bootstrap/etc/sx/models/common_bitrix/abstract +1 -0
  16. data/bootstrap/etc/sx/models/common_bitrix/container/mux +1 -0
  17. data/bootstrap/etc/sx/models/common_bitrix/inherit +1 -0
  18. data/bootstrap/etc/sx/models/common_bitrix/site/php/admin_value +2 -0
  19. data/bootstrap/etc/sx/models/common_bitrix/site/php/flag +1 -0
  20. data/bootstrap/etc/sx/models/common_bitrix/site/php/value +6 -0
  21. data/bootstrap/etc/sx/models/common_fcgi/abstract +1 -0
  22. data/bootstrap/etc/sx/models/common_fcgi/container/config.rb +6 -0
  23. data/bootstrap/etc/sx/models/common_fcgi/container/config_templates/supervisord.conf.erb +16 -0
  24. data/bootstrap/etc/sx/models/common_fcgi/container/docker/image +1 -0
  25. data/bootstrap/etc/sx/models/common_fcgi/container/docker/user.erb +1 -0
  26. data/bootstrap/etc/sx/models/common_fcgi/container/system_users +1 -0
  27. data/bootstrap/etc/sx/models/common_fcgi/site/config.rb +4 -0
  28. data/bootstrap/etc/sx/models/common_fcgi/site/config_templates/nginx_vhost.erb +21 -0
  29. data/bootstrap/etc/sx/models/common_joomla/abstract +1 -0
  30. data/bootstrap/etc/sx/models/common_joomla/site/php/flag +1 -0
  31. data/bootstrap/etc/sx/models/common_joomla/site/php/value +2 -0
  32. data/bootstrap/etc/sx/models/common_joomla_v2/abstract +1 -0
  33. data/bootstrap/etc/sx/models/common_joomla_v2/container/mux +1 -0
  34. data/bootstrap/etc/sx/models/common_joomla_v2/inherit +2 -0
  35. data/bootstrap/etc/sx/models/common_joomla_v3/abstract +1 -0
  36. data/bootstrap/etc/sx/models/common_joomla_v3/container/mux +1 -0
  37. data/bootstrap/etc/sx/models/common_joomla_v3/inherit +2 -0
  38. data/bootstrap/etc/sx/models/common_l/abstract +1 -0
  39. data/bootstrap/etc/sx/models/common_l/container/docker/blkio_weight +1 -0
  40. data/bootstrap/etc/sx/models/common_l/container/docker/cpu_period +1 -0
  41. data/bootstrap/etc/sx/models/common_l/container/docker/cpu_quota +1 -0
  42. data/bootstrap/etc/sx/models/common_l/container/docker/cpu_shares +1 -0
  43. data/bootstrap/etc/sx/models/common_l/container/docker/memory +1 -0
  44. data/bootstrap/etc/sx/models/common_l/container/docker/memory_swap +1 -0
  45. data/bootstrap/etc/sx/models/common_m/abstract +1 -0
  46. data/bootstrap/etc/sx/models/common_m/container/docker/blkio_weight +1 -0
  47. data/bootstrap/etc/sx/models/common_m/container/docker/cpu_period +1 -0
  48. data/bootstrap/etc/sx/models/common_m/container/docker/cpu_quota +1 -0
  49. data/bootstrap/etc/sx/models/common_m/container/docker/cpu_shares +1 -0
  50. data/bootstrap/etc/sx/models/common_m/container/docker/memory +1 -0
  51. data/bootstrap/etc/sx/models/common_m/container/docker/memory_swap +1 -0
  52. data/bootstrap/etc/sx/models/common_mail/abstract +1 -0
  53. data/bootstrap/etc/sx/models/common_mail/container/config.rb +12 -0
  54. data/bootstrap/etc/sx/models/common_mail/container/config_templates/postfwd_rules.erb +12 -0
  55. data/bootstrap/etc/sx/models/common_mail/container/config_templates/ssmtp.conf.erb +6 -0
  56. data/bootstrap/etc/sx/models/common_mail/container/mail/daily_limit +1 -0
  57. data/bootstrap/etc/sx/models/common_mail/container/mail/enabled +1 -0
  58. data/bootstrap/etc/sx/models/common_mail/container/mail/hourly_limit +1 -0
  59. data/bootstrap/etc/sx/models/common_php_l/abstract +1 -0
  60. data/bootstrap/etc/sx/models/common_php_l/container/mail/daily_limit +1 -0
  61. data/bootstrap/etc/sx/models/common_php_l/container/mail/hourly_limit +1 -0
  62. data/bootstrap/etc/sx/models/common_php_l/inherit +1 -0
  63. data/bootstrap/etc/sx/models/common_php_l/site/php/pm +1 -0
  64. data/bootstrap/etc/sx/models/common_php_l/site/php/pm_max_children +1 -0
  65. data/bootstrap/etc/sx/models/common_php_l/site/php/pm_max_spare_servers +1 -0
  66. data/bootstrap/etc/sx/models/common_php_l/site/php/pm_min_spare_servers +1 -0
  67. data/bootstrap/etc/sx/models/common_php_l/site/php/pm_start_servers +1 -0
  68. data/bootstrap/etc/sx/models/common_php_m/abstract +1 -0
  69. data/bootstrap/etc/sx/models/common_php_m/inherit +1 -0
  70. data/bootstrap/etc/sx/models/common_php_m/site/php/pm_max_children +1 -0
  71. data/bootstrap/etc/sx/models/common_php_s/abstract +1 -0
  72. data/bootstrap/etc/sx/models/common_php_s/inherit +1 -0
  73. data/bootstrap/etc/sx/models/common_php_xl/abstract +1 -0
  74. data/bootstrap/etc/sx/models/common_php_xl/container/mail/daily_limit +1 -0
  75. data/bootstrap/etc/sx/models/common_php_xl/container/mail/hourly_limit +1 -0
  76. data/bootstrap/etc/sx/models/common_php_xl/inherit +1 -0
  77. data/bootstrap/etc/sx/models/common_php_xl/site/php/pm +1 -0
  78. data/bootstrap/etc/sx/models/common_php_xl/site/php/pm_max_children +1 -0
  79. data/bootstrap/etc/sx/models/common_php_xl/site/php/pm_max_spare_servers +1 -0
  80. data/bootstrap/etc/sx/models/common_php_xl/site/php/pm_min_spare_servers +1 -0
  81. data/bootstrap/etc/sx/models/common_php_xl/site/php/pm_start_servers +1 -0
  82. data/bootstrap/etc/sx/models/common_php_xs/abstract +1 -0
  83. data/bootstrap/etc/sx/models/common_php_xs/container/mail/daily_limit +1 -0
  84. data/bootstrap/etc/sx/models/common_php_xs/container/mail/hourly_limit +1 -0
  85. data/bootstrap/etc/sx/models/common_php_xs/inherit +1 -0
  86. data/bootstrap/etc/sx/models/common_php_xs/site/php/pm_max_children +1 -0
  87. data/bootstrap/etc/sx/models/common_s/abstract +1 -0
  88. data/bootstrap/etc/sx/models/common_s/container/docker/blkio_weight +1 -0
  89. data/bootstrap/etc/sx/models/common_s/container/docker/cpu_period +1 -0
  90. data/bootstrap/etc/sx/models/common_s/container/docker/cpu_quota +1 -0
  91. data/bootstrap/etc/sx/models/common_s/container/docker/cpu_shares +1 -0
  92. data/bootstrap/etc/sx/models/common_s/container/docker/memory +1 -0
  93. data/bootstrap/etc/sx/models/common_s/container/docker/memory_swap +1 -0
  94. data/bootstrap/etc/sx/models/common_symfony/abstract +1 -0
  95. data/bootstrap/etc/sx/models/common_symfony/container/mux +1 -0
  96. data/bootstrap/etc/sx/models/common_symfony/container/system_users +1 -0
  97. data/bootstrap/etc/sx/models/common_symfony/inherit +1 -0
  98. data/bootstrap/etc/sx/models/common_symfony/site/php/flag +3 -0
  99. data/bootstrap/etc/sx/models/common_symfony/site/php/user +1 -0
  100. data/bootstrap/etc/sx/models/common_symfony/site/use_apache +1 -0
  101. data/bootstrap/etc/sx/models/common_xl/abstract +1 -0
  102. data/bootstrap/etc/sx/models/common_xl/container/docker/blkio_weight +1 -0
  103. data/bootstrap/etc/sx/models/common_xl/container/docker/cpu_shares +1 -0
  104. data/bootstrap/etc/sx/models/common_xl/container/docker/memory +1 -0
  105. data/bootstrap/etc/sx/models/common_xl/container/docker/memory_swap +1 -0
  106. data/bootstrap/etc/sx/models/common_xs/abstract +1 -0
  107. data/bootstrap/etc/sx/models/common_xs/container/docker/blkio_weight +1 -0
  108. data/bootstrap/etc/sx/models/common_xs/container/docker/cpu_period +1 -0
  109. data/bootstrap/etc/sx/models/common_xs/container/docker/cpu_quota +1 -0
  110. data/bootstrap/etc/sx/models/common_xs/container/docker/cpu_shares +1 -0
  111. data/bootstrap/etc/sx/models/common_xs/container/docker/memory +1 -0
  112. data/bootstrap/etc/sx/models/common_xs/container/docker/memory_swap +1 -0
  113. data/bootstrap/etc/sx/models/fcgi_l/inherit +3 -0
  114. data/bootstrap/etc/sx/models/fcgi_m/inherit +3 -0
  115. data/bootstrap/etc/sx/models/fcgi_s/inherit +3 -0
  116. data/bootstrap/etc/sx/models/fcgi_xl/inherit +3 -0
  117. data/bootstrap/etc/sx/models/joomla_v2_l/inherit +3 -0
  118. data/bootstrap/etc/sx/models/joomla_v2_m/inherit +3 -0
  119. data/bootstrap/etc/sx/models/joomla_v2_s/inherit +3 -0
  120. data/bootstrap/etc/sx/models/joomla_v2_xs/inherit +3 -0
  121. data/bootstrap/etc/sx/models/joomla_v3_l/inherit +3 -0
  122. data/bootstrap/etc/sx/models/joomla_v3_m/inherit +3 -0
  123. data/bootstrap/etc/sx/models/joomla_v3_s/inherit +3 -0
  124. data/bootstrap/etc/sx/models/joomla_v3_xs/inherit +3 -0
  125. data/bootstrap/etc/sx/models/symfony_l/inherit +3 -0
  126. data/bootstrap/etc/sx/models/symfony_m/inherit +3 -0
  127. data/bootstrap/etc/sx/models/symfony_xl/inherit +3 -0
  128. data/bootstrap/etc/sx/models/test/container/config.rb +4 -0
  129. data/bootstrap/etc/sx/models/test/container/config_templates/supervisord.conf.erb +16 -0
  130. data/bootstrap/etc/sx/models/test/container/docker/blkio_weight +1 -0
  131. data/bootstrap/etc/sx/models/test/container/docker/command +1 -0
  132. data/bootstrap/etc/sx/models/test/container/docker/cpu_period +1 -0
  133. data/bootstrap/etc/sx/models/test/container/docker/cpu_quota +1 -0
  134. data/bootstrap/etc/sx/models/test/container/docker/cpu_shares +1 -0
  135. data/bootstrap/etc/sx/models/test/container/docker/image +1 -0
  136. data/bootstrap/etc/sx/models/test/container/docker/memory +1 -0
  137. data/bootstrap/etc/sx/models/test/container/docker/memory_swap +1 -0
  138. data/bootstrap/etc/sx/models/test/container/docker/user.erb +1 -0
  139. data/bootstrap/etc/sx/models/test/container/docker/volume.erb +2 -0
  140. data/bootstrap/etc/sx/models/test/container/system_users +1 -0
  141. data/bootstrap/etc/sx/models/test/site/config.rb +4 -0
  142. data/bootstrap/etc/sx/models/test/site/config_templates/nginx_vhost.erb +21 -0
  143. data/bootstrap/etc/sx/models/test_with_mux/container/mux +1 -0
  144. data/bootstrap/etc/sx/models/test_with_mux/inherit +1 -0
  145. data/bootstrap/etc/sx/muxs/base/docker/command +1 -0
  146. data/bootstrap/etc/sx/muxs/php-5.3/container/docker/image +1 -0
  147. data/bootstrap/etc/sx/muxs/php-5.3/docker/image +1 -0
  148. data/bootstrap/etc/sx/muxs/php-5.3/inherit +2 -0
  149. data/bootstrap/etc/sx/muxs/php-5.5/container/docker/image +1 -0
  150. data/bootstrap/etc/sx/muxs/php-5.5/docker/image +1 -0
  151. data/bootstrap/etc/sx/muxs/php-5.5/inherit +2 -0
  152. data/bootstrap/etc/sx/muxs/php-5.6/container/docker/image +1 -0
  153. data/bootstrap/etc/sx/muxs/php-5.6/docker/image +1 -0
  154. data/bootstrap/etc/sx/muxs/php-5.6/inherit +2 -0
  155. data/bootstrap/etc/sx/muxs/php/abstract +1 -0
  156. data/bootstrap/etc/sx/muxs/php/docker/pid +1 -0
  157. data/bootstrap/etc/sx/muxs/php/docker/privileged +1 -0
  158. data/bootstrap/etc/sx/muxs/php/docker/volume +3 -0
  159. data/bootstrap/etc/sx/muxs/php/site/config.rb +10 -0
  160. data/bootstrap/etc/sx/muxs/php/site/config_templates/apache_vhost.erb +26 -0
  161. data/bootstrap/etc/sx/muxs/php/site/config_templates/nginx_vhost.erb +39 -0
  162. data/bootstrap/etc/sx/muxs/php/site/config_templates/php_fpm_pool.erb +22 -0
  163. data/bootstrap/etc/sx/muxs/php/site/php/pm +1 -0
  164. data/bootstrap/etc/sx/muxs/php/site/php/pm_max_children +1 -0
  165. data/bootstrap/etc/sx/muxs/php/site/use_apache +1 -0
  166. data/bootstrap/etc/sx/muxs/test/container/docker/image +1 -0
  167. data/bootstrap/etc/sx/muxs/test/docker/command +1 -0
  168. data/bootstrap/etc/sx/muxs/test/docker/image +1 -0
  169. data/bootstrap/etc/sx/muxs/test/inherit +1 -0
  170. data/bootstrap/etc/sx/password_strength +1 -0
  171. data/bootstrap/etc/sx/smtp_hostname +1 -0
  172. data/dockerfile/almost_base +19 -0
  173. data/dockerfile/base +18 -0
  174. data/dockerfile/mux +6 -0
  175. data/lib/superhosting.rb +39 -5
  176. data/lib/superhosting/base.rb +15 -21
  177. data/lib/superhosting/cli/base.rb +56 -40
  178. data/lib/superhosting/cli/cmd/admin_add.rb +5 -0
  179. data/lib/superhosting/cli/cmd/admin_container_list.rb +4 -0
  180. data/lib/superhosting/cli/cmd/admin_list.rb +11 -0
  181. data/lib/superhosting/cli/cmd/admin_passwd.rb +4 -0
  182. data/lib/superhosting/cli/cmd/container_admin_list.rb +4 -0
  183. data/lib/superhosting/cli/cmd/container_inspect.rb +11 -0
  184. data/lib/superhosting/cli/cmd/container_list.rb +18 -0
  185. data/lib/superhosting/cli/cmd/container_reconfigure.rb +11 -0
  186. data/lib/superhosting/cli/cmd/container_rename.rb +16 -0
  187. data/lib/superhosting/cli/cmd/model_list.rb +11 -0
  188. data/lib/superhosting/cli/cmd/{container_reconfig.rb → model_reconfigure.rb} +1 -1
  189. data/lib/superhosting/cli/cmd/model_tree.rb +30 -0
  190. data/lib/superhosting/cli/cmd/model_update.rb +11 -0
  191. data/lib/superhosting/cli/cmd/mux_reconfigure.rb +11 -0
  192. data/lib/superhosting/cli/cmd/repair.rb +8 -0
  193. data/lib/superhosting/cli/cmd/site_container.rb +15 -0
  194. data/lib/superhosting/cli/cmd/site_inspect.rb +11 -0
  195. data/lib/superhosting/cli/cmd/site_list.rb +35 -0
  196. data/lib/superhosting/cli/cmd/site_name.rb +15 -0
  197. data/lib/superhosting/cli/cmd/site_reconfigure.rb +11 -0
  198. data/lib/superhosting/cli/cmd/site_rename.rb +4 -0
  199. data/lib/superhosting/cli/cmd/user_add.rb +11 -5
  200. data/lib/superhosting/cli/cmd/user_change.rb +12 -6
  201. data/lib/superhosting/cli/cmd/user_list.rb +7 -0
  202. data/lib/superhosting/cli/cmd/user_passwd.rb +9 -0
  203. data/lib/superhosting/composite_mapper.rb +12 -0
  204. data/lib/superhosting/composite_mapper/base.rb +17 -0
  205. data/lib/superhosting/composite_mapper/container.rb +9 -0
  206. data/lib/superhosting/composite_mapper/site.rb +13 -0
  207. data/lib/superhosting/config/net_status.yml +122 -0
  208. data/lib/superhosting/config_executor.rb +12 -0
  209. data/lib/superhosting/{script_executor → config_executor}/base.rb +6 -5
  210. data/lib/superhosting/config_executor/container.rb +69 -0
  211. data/lib/superhosting/config_executor/site.rb +18 -0
  212. data/lib/superhosting/controller/admin.rb +84 -4
  213. data/lib/superhosting/controller/admin/container.rb +62 -2
  214. data/lib/superhosting/controller/base.rb +18 -0
  215. data/lib/superhosting/controller/container.rb +185 -122
  216. data/lib/superhosting/controller/container/admin.rb +25 -3
  217. data/lib/superhosting/controller/container/states.rb +296 -0
  218. data/lib/superhosting/controller/model.rb +62 -0
  219. data/lib/superhosting/controller/mux.rb +88 -0
  220. data/lib/superhosting/controller/mysql.rb +2 -2
  221. data/lib/superhosting/controller/site.rb +217 -72
  222. data/lib/superhosting/controller/site/alias.rb +32 -6
  223. data/lib/superhosting/controller/site/states.rb +41 -0
  224. data/lib/superhosting/controller/user.rb +233 -4
  225. data/lib/superhosting/docker_api.rb +170 -6
  226. data/lib/superhosting/helper/cmd.rb +40 -0
  227. data/lib/superhosting/helper/config.rb +80 -0
  228. data/lib/superhosting/helper/file.rb +56 -0
  229. data/lib/superhosting/helper/i18n.rb +13 -0
  230. data/lib/superhosting/helper/logger.rb +136 -0
  231. data/lib/superhosting/helper/states.rb +69 -0
  232. data/lib/superhosting/helpers.rb +5 -21
  233. data/lib/superhosting/mapper_inheritance/base.rb +16 -0
  234. data/lib/superhosting/mapper_inheritance/model.rb +96 -0
  235. data/lib/superhosting/mapper_inheritance/mux.rb +49 -0
  236. data/lib/superhosting/patches/path_mapper/dir_node.rb +23 -0
  237. data/lib/superhosting/patches/path_mapper/file_node.rb +47 -0
  238. data/lib/superhosting/patches/path_mapper/null_node.rb +35 -0
  239. data/lib/superhosting/patches/string/punycode.rb +21 -0
  240. data/lib/superhosting/version.rb +1 -1
  241. data/provision/bootstrap.sh +11 -0
  242. data/provision/docker.sh +25 -0
  243. data/provision/pam_docker.sh +5 -0
  244. data/{bootstrap.sh → provision/vagrant.sh} +5 -8
  245. data/superhosting.gemspec +14 -3
  246. metadata +368 -12
  247. data/lib/superhosting/script_executor/container.rb +0 -36
  248. data/lib/superhosting/script_executor/site.rb +0 -13
@@ -2,11 +2,11 @@ module Superhosting
2
2
  module Controller
3
3
  class Mysql < Base
4
4
  def db
5
- Db.new
5
+ self.get_controller(Db)
6
6
  end
7
7
 
8
8
  def user
9
- User.new
9
+ self.get_controller(User)
10
10
  end
11
11
 
12
12
  def grant
@@ -1,105 +1,250 @@
1
1
  module Superhosting
2
2
  module Controller
3
3
  class Site < Base
4
- attr_reader :site_index
5
-
6
- DOMAIN_NAME_FORMAT = /^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\.)+[A-Za-z]{2,6}$/
7
-
8
- def site_index
9
- def generate
10
- @site_index = {}
11
- @config.containers._grep_dirs.each do |c|
12
- c.sites._grep_dirs.each do |s|
13
- names = []
14
- names << s._name
15
- s.aliases.lines {|n| names << n.strip } unless s.aliases.nil?
16
- raise NetStatus::Exception.new(error: :error, message: "Conflict between container_sites: '#{@site_index[s._name][:site]._path}' and '#{s._path}'") if @site_index.key? s._name
17
- names.each {|n| @site_index[n] = { container: c, site: s } }
4
+ DOMAIN_NAME_FORMAT = /^((?!-)[А-Яа-яA-Za-z0-9-]{1,63}(?<!-)\.)+[А-Яа-яA-Za-z]{2,6}$/
5
+
6
+ def initialize(**kwargs)
7
+ super(**kwargs)
8
+ @container_controller = self.get_controller(Container)
9
+ self.index
10
+ end
11
+
12
+ def list(container_name: nil)
13
+ if container_name.nil? or (resp = @container_controller.available_validation(name: container_name)).net_status_ok?
14
+ { data: self._list(container_name: container_name) }
15
+ else
16
+ resp
17
+ end
18
+ end
19
+
20
+ def _list(container_name: nil)
21
+ def data(name)
22
+ mapper = self.index[name][:mapper]
23
+ docker_options = mapper.docker.grep_files.map {|f| [f.name, f.value] }.to_h
24
+ configs = mapper.f('config.rb', overlay: false).reverse.map {|f| f.value }
25
+ { docker: docker_options, configs: configs, aliases: self.index[name][:aliases]-[name] }
26
+ end
27
+
28
+ sites = {}
29
+ if container_name
30
+ container_mapper = @container_controller.index[container_name][:mapper]
31
+ container_mapper.sites.grep_dirs.each do |mapper|
32
+ name = mapper.name
33
+ if (state = container_mapper.lib.sites.f(name).state).file?
34
+ sites[name] = { state: state.value, container: container_name }.merge(data(name))
35
+ end
36
+ end
37
+ else
38
+ self.index.values.each do |index|
39
+ name = index[:mapper].name
40
+ if (state = index[:state_mapper]).file?
41
+ sites[name] = { state: state.value, container: index[:container_mapper].name }.merge(data(name))
18
42
  end
19
43
  end
20
- @site_index
21
44
  end
22
45
 
23
- @site_index ||= self.generate
46
+ sites
24
47
  end
25
48
 
26
- def add(name:, container_name:)
27
- return { error: :input_error, message: "Invalid site name '#{name}' only '#{DOMAIN_NAME_FORMAT}'" } if name !~ DOMAIN_NAME_FORMAT
28
- return { error: :logical_error, message: 'Site already exists.' } if self.site_index.include? name
29
- return { error: :logical_error, message: "Container '#{container_name}' doesn\'t exists." } if (config_path_mapper = @config.containers.f(container_name)).nil?
30
-
31
- site_mapper = config_path_mapper.sites.f(name)
32
- FileUtils.mkdir_p site_mapper._path
49
+ def inspect(name:)
50
+ if (resp = self.existing_validation(name: name)).net_status_ok?
51
+ actual_name = self.index[name][:mapper].name
52
+ container_mapper = self.index[name][:container_mapper]
53
+ { data: self._list(container_name: container_mapper.name)[actual_name] }
54
+ else
55
+ resp
56
+ end
57
+ end
33
58
 
34
- lib_path_mapper = PathMapper.new("#{@lib_path}/containers/#{container_name}")
35
- model = config_path_mapper.model(default: @config.default_model)
36
- model_mapper = @config.models.f(:"#{model}")
59
+ def add(name:, container_name:)
60
+ if (resp = @container_controller.available_validation(name: container_name)).net_status_ok? and
61
+ (resp = self.adding_validation(name: name)).net_status_ok?
62
+ resp = self._reconfigure(name: name, container_name: container_name)
63
+ end
64
+ resp
65
+ end
37
66
 
38
- lib_sites_path = lib_path_mapper.registry.sites
39
- unless model_mapper.f('site.rb').nil?
40
- registry_path = lib_sites_path.f(name)._path
41
- FileUtils.mkdir_p lib_sites_path._path
42
- ex = ScriptExecutor::Site.new(
43
- site: site_mapper, site_name: name,
44
- container: config_path_mapper, container_name: name, container_lib: lib_path_mapper, registry_path: registry_path,
45
- model: model_mapper, config: @config, lib: @lib
46
- )
47
- ex.execute(model_mapper.f('site.rb'))
48
- ex.commands.each {|c| self.command c }
67
+ def name(name:)
68
+ if (resp = self.existing_validation(name: name)).net_status_ok?
69
+ { data: self.index[name][:mapper].name }
70
+ else
71
+ resp
49
72
  end
73
+ end
50
74
 
51
- {}
75
+ def container(name:)
76
+ if (resp = self.existing_validation(name: name)).net_status_ok?
77
+ { data: self.index[name][:container_mapper].name }
78
+ else
79
+ resp
80
+ end
52
81
  end
53
82
 
54
83
  def delete(name:)
55
- if site = self.site_index[name]
56
- FileUtils.rm_rf site[:site]._path
57
- container_sites = site[:container].sites
58
- FileUtils.rm_rf container_sites._path if container_sites.nil?
84
+ if (resp = self.existing_validation(name: name)).net_status_ok?
85
+ lib_sites_mapper = self.index[name][:container_mapper].lib.sites
86
+ actual_name = self.index[name][:mapper].name
87
+ state_mapper = lib_sites_mapper.f(actual_name)
88
+
89
+ states = {
90
+ up: { action: :unapply, undo: :apply, next: :configured },
91
+ configured: { action: :unconfigure, next: :data_installed },
92
+ data_installed: { action: :uninstall_data },
93
+ }
94
+
95
+ self.on_state(state_mapper: state_mapper, states: states, name: actual_name)
96
+ end
97
+ resp
98
+ end
59
99
 
60
- config_path_mapper = site[:container]
61
- lib_path_mapper = PathMapper.new("#{@lib_path}/containers/#{config_path_mapper._name}")
62
- model = config_path_mapper.model(default: @config.default_model)
63
- model_mapper = @config.models.f(:"#{model}")
100
+ def rename(name:, new_name:, alias_name: false)
101
+ if (resp = self.available_validation(name: name)).net_status_ok? and
102
+ ((resp = self.adding_validation(name: new_name)).net_status_ok? or
103
+ (is_alias = alias_existing_validation(name: name, alias_name: new_name)))
64
104
 
65
- lib_sites_path = lib_path_mapper.registry.sites
105
+ mapper = self.index[name][:mapper]
106
+ container_mapper = self.index[name][:container_mapper]
107
+ actual_name = mapper.name
66
108
 
67
- unless (registry_site = lib_sites_path.f(name)).nil?
68
- FileUtils.rm registry_site.lines
69
- FileUtils.rm registry_site._path
70
- end
109
+ mapper.aliases_mapper.remove_line!(new_name) if defined? is_alias and is_alias
110
+ self.reindex_container_sites(container_name: container_mapper.name)
71
111
 
72
- unless model_mapper.f('site.rb').nil?
73
- registry_path = lib_sites_path.f(name)._path
74
- FileUtils.mkdir_p lib_sites_path._path
75
- ex = ScriptExecutor::Site.new(
76
- site: site[:site], site_name: name,
77
- container: config_path_mapper, container_name: name, container_lib: lib_path_mapper,
78
- registry_path: registry_path, on_reconfig_only: true,
79
- model: model_mapper, config: @config, lib: @lib
80
- )
81
- ex.execute(model_mapper.f('site.rb'))
82
- ex.commands.each {|c| self.command c }
112
+ begin
113
+ self.unconfigure_with_unapply(name: actual_name).net_status_ok!
114
+ if (resp = self._reconfigure(name: new_name, container_name: container_mapper.name)).net_status_ok?
115
+ new_mapper = self.index[new_name][:mapper]
116
+ mapper.etc.rename!(new_mapper.etc.path)
117
+ mapper.lib.rename!(new_mapper.lib.path)
118
+ mapper.aliases_mapper.rename!(new_mapper.aliases_mapper.path)
119
+
120
+ self.reconfigure(name: new_name).net_status_ok!
121
+ self.delete(name: actual_name).net_status_ok!
122
+
123
+ new_mapper.aliases_mapper.append_line!(actual_name) if alias_name
124
+ self.reindex_container_sites(container_name: container_mapper.name)
125
+ end
126
+ rescue Exception => e
127
+ resp = e.net_status
128
+ raise
129
+ ensure
130
+ unless resp.net_status_ok?
131
+ unless new_mapper.nil?
132
+ mapper.aliases_mapper.append_line!(new_name) if defined? is_alias and is_alias
133
+ mapper.aliases_mapper.remove_line!(name) if alias_name
134
+
135
+ new_mapper.etc.rename!(mapper.path)
136
+ new_mapper.lib.rename!(mapper.lib.path)
137
+
138
+ self.reconfigure(name: name)
139
+ end
140
+
141
+ self.delete(name: new_name)
142
+ end
83
143
  end
144
+ end
145
+ resp
146
+ end
84
147
 
85
- {}
148
+ def reconfigure(name:)
149
+ if (resp = self.existing_validation(name: name)).net_status_ok?
150
+ actual_name = self.index[name][:mapper].name
151
+ self.set_state(name: actual_name, state: :data_installed)
152
+ self._reconfigure(name: actual_name)
86
153
  end
154
+ resp
87
155
  end
88
156
 
89
- def rename(name:, new_name:)
90
- return { error: :logical_error, message: "Site '#{name}' doesn't exists." } unless site = self.site_index[name]
91
- return { error: :logical_error, message: "Site '#{new_name}' already exists." } if self.site_index[new_name]
157
+ def _reconfigure(name:, **kwargs)
158
+ lib_sites_mapper = if (container_name = kwargs[:container_name])
159
+ @container_controller.index[container_name][:mapper].lib.sites
160
+ else
161
+ self.index[name][:container_mapper].lib.sites
162
+ end
163
+ state_mapper = lib_sites_mapper.f(name)
92
164
 
93
- FileUtils.mv site[:container].sites.f(name)._path, site[:container].sites.f(new_name)._path
165
+ states = {
166
+ none: { action: :install_data, undo: :uninstall_data, next: :data_installed },
167
+ data_installed: { action: :configure_with_apply, undo: :unconfigure_with_unapply, next: :up },
168
+ }
94
169
 
95
- lib_path_mapper = PathMapper.new("#{@lib_path}/containers/#{site[:container]._name}")
96
- unless (lib_sites_path = lib_path_mapper.registry.sites).nil?
97
- FileUtils.mv lib_sites_path.f(name), lib_sites_path.f(new_name)
170
+ self.on_state(state_mapper: state_mapper, states: states,
171
+ name: name, container_name: container_name, **kwargs)
172
+ end
173
+
174
+ def alias(name:)
175
+ self.get_controller(Alias, name: name)
176
+ end
177
+
178
+ def adding_validation(name:)
179
+ return { error: :input_error, code: :invalid_site_name, data: { name: name, regex: DOMAIN_NAME_FORMAT } } if name !~ DOMAIN_NAME_FORMAT
180
+ self.not_existing_validation(name: name)
181
+ end
182
+
183
+ def existing_validation(name:)
184
+ self.index[name].nil? ? { error: :logical_error, code: :site_does_not_exists, data: { name: name } } : {}
185
+ end
186
+
187
+ def alias_existing_validation(name:, alias_name:)
188
+ self.index[name][:mapper].aliases.include?(alias_name)
189
+ end
190
+
191
+ def not_existing_validation(name:)
192
+ self.existing_validation(name: name).net_status_ok? ? { error: :logical_error, code: :site_exists, data: { name: name} } : {}
193
+ end
194
+
195
+ def available_validation(name:)
196
+ if (resp = self.existing_validation(name: name)).net_status_ok?
197
+ resp = (self.index[name][:state_mapper].value == 'up') ? {} : { error: :logical_error, code: :site_is_not_available, data: { name: name } }
198
+ end
199
+ resp
200
+ end
201
+
202
+ def index
203
+ @@index ||= self.reindex
204
+ end
205
+
206
+ def reindex
207
+ @config.containers.grep_dirs.each do |container_mapper|
208
+ reindex_container_sites(container_name: container_mapper.name)
98
209
  end
210
+ @@index ||= {}
99
211
  end
100
212
 
101
- def alias(name:, logger: @logger)
102
- Alias.new(name: name, logger: logger)
213
+ def reindex_container_sites(container_name:)
214
+ @config.containers.f(container_name).sites.grep_dirs.each do |site_mapper|
215
+ self.reindex_site(name: site_mapper.name, container_name: container_name)
216
+ end
217
+ end
218
+
219
+ def reindex_site(name:, container_name:)
220
+ @@index ||= {}
221
+ @@index[name][:aliases].each{|n| @@index.delete(n) } if @@index[name]
222
+
223
+ container_mapper = @container_controller.index[container_name][:mapper]
224
+ etc_mapper = container_mapper.sites.f(name)
225
+ lib_mapper = container_mapper.lib.web.f(name)
226
+ web_mapper = container_mapper.web.f(name)
227
+ state_mapper = container_mapper.lib.sites.f(name).state
228
+
229
+ if etc_mapper.nil?
230
+ @@index.delete(name)
231
+ return
232
+ end
233
+
234
+ model_name = container_mapper.f('model', default: @config.default_model)
235
+ model_mapper = @config.models.f(model_name)
236
+ etc_mapper = MapperInheritance::Model.new(model_mapper).set_inheritors(etc_mapper)
237
+
238
+ mapper = CompositeMapper.new(etc_mapper: etc_mapper, lib_mapper: lib_mapper, web_mapper: web_mapper)
239
+ etc_mapper.erb_options = { site: mapper, container: mapper }
240
+
241
+ if @@index.key? name and @@index[name][:mapper].path != mapper.path
242
+ raise NetStatus::Exception, { code: :container_site_name_conflict,
243
+ data: { site1: @@index[name][:mapper].path, site2: mapper.path } }
244
+ end
245
+
246
+ names = ([mapper.name] + mapper.aliases)
247
+ names.each {|name| @@index[name] = { mapper: mapper, container_mapper: container_mapper, state_mapper: state_mapper, aliases: names } }
103
248
  end
104
249
  end
105
250
  end
@@ -2,18 +2,44 @@ module Superhosting
2
2
  module Controller
3
3
  class Site
4
4
  class Alias < Base
5
- def initialize(name:, **kvargs)
6
- raise NetStatus::Exception, { error: :logical_error, message: "Site '#{name}' doesn't exists." } unless @site_descriptor = Site.new(kvargs).site_index[name]
7
- super(kvargs)
5
+ def initialize(name:, **kwargs)
6
+ super(kwargs)
7
+ @site_controller = self.get_controller(Site)
8
+ @site_controller.existing_validation(name: name).net_status_ok!
9
+
10
+ site = @site_controller.index[name]
11
+ @site_mapper = site[:mapper]
12
+ @aliases_mapper = site[:mapper].aliases_mapper
13
+ @container_mapper = site[:container_mapper]
8
14
  end
9
15
 
10
16
  def add(name:)
11
- return { error: :input_error, message: "Invalid alias name '#{name}' - only '#{Site::DOMAIN_NAME_FORMAT}' are allowed" } if name !~ Site::DOMAIN_NAME_FORMAT
12
- write_if_not_exist(@site_descriptor[:site].aliases._path, name)
17
+ if (resp = self.not_existing_validation(name: name)).net_status_ok? and
18
+ (resp = @site_controller.adding_validation(name: name)).net_status_ok?
19
+ @aliases_mapper.append_line!(name)
20
+ @site_controller.reconfigure(name: @site_mapper.name)
21
+
22
+ @site_controller.reindex_site(name: @site_mapper.name, container_name: @container_mapper.name)
23
+ end
24
+ resp
13
25
  end
14
26
 
15
27
  def delete(name:)
16
- remove_line_from_file(@site_descriptor[:site].aliases._path, name)
28
+ if (resp = self.existing_validation(name: name)).net_status_ok?
29
+ @aliases_mapper.remove_line!(name)
30
+ @site_controller.reconfigure(name: @site_mapper.name)
31
+
32
+ @site_controller.reindex_site(name: @site_mapper.name, container_name: @container_mapper.name)
33
+ end
34
+ resp
35
+ end
36
+
37
+ def existing_validation(name:)
38
+ @aliases_mapper.lines.include?(name) ? {} : { error: :logical_error, code: :alias_does_not_exists, data: { name: name } }
39
+ end
40
+
41
+ def not_existing_validation(name:)
42
+ self.existing_validation(name: name).net_status_ok? ? { error: :logical_error, code: :alias_exists, data: { name: name } } : {}
17
43
  end
18
44
  end
19
45
  end
@@ -0,0 +1,41 @@
1
+ module Superhosting
2
+ module Controller
3
+ class Site
4
+ include Helper::States
5
+
6
+ def install_data(name:, container_name:)
7
+ container_mapper = @container_controller.index[container_name][:mapper]
8
+ container_mapper.sites.f(name).create!
9
+ site_lib_mapper = container_mapper.lib.web.f(name).create!
10
+
11
+ chown_r!(container_name, container_name, site_lib_mapper.path)
12
+
13
+ self.reindex_site(name: name, container_name: container_name)
14
+ {}
15
+ end
16
+
17
+ def uninstall_data(name:)
18
+ if self.index.include? name
19
+ container_mapper = self.index[name][:container_mapper]
20
+ container_mapper.sites.f(name).delete!
21
+ container_mapper.lib.web.f(name).delete!
22
+ container_mapper.lib.sites.f(name).aliases.delete!
23
+
24
+ self.reindex_site(name: name, container_name: container_mapper.name)
25
+ end
26
+ {}
27
+ end
28
+
29
+ def _config_options(name:, on_reconfig:, on_config:)
30
+ mapper = self.index[name][:mapper]
31
+ container_mapper = self.index[name][:container_mapper]
32
+ registry_mapper = container_mapper.lib.registry.sites.f(name)
33
+
34
+ @container_controller._config_options(name: container_mapper.name, on_reconfig: on_reconfig, on_config: on_config).merge! ({
35
+ site: mapper,
36
+ registry_mapper: registry_mapper
37
+ })
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,24 +1,253 @@
1
1
  module Superhosting
2
2
  module Controller
3
3
  class User < Base
4
- def list
4
+ USER_NAME_FORMAT = /^[a-zA-Z][-a-zA-Z0-9_]{,31}$/
5
5
 
6
+ def initialize(**kwargs)
7
+ super(**kwargs)
8
+ @container_controller = self.get_controller(Container)
6
9
  end
7
10
 
8
- def add(name:, container_name:, no_ssh: false, no_ftp: false)
11
+ def list(container_name:)
12
+ if (resp = @container_controller.available_validation(name: container_name)).net_status_ok?
13
+ { data: self._list(container_name: container_name) }
14
+ else
15
+ resp
16
+ end
17
+ end
9
18
 
19
+ def _list(container_name:)
20
+ self._group_get_users_names(name: container_name)
10
21
  end
11
22
 
12
- def passwd(generate:)
23
+ def add(name:, container_name:, ftp_dir: nil, ftp_only: false, generate: false)
24
+ return { error: :logical_error, code: :option_ftp_only_is_required } if ftp_dir and !ftp_only
25
+
26
+ web_mapper = PathMapper.new("/web/#{container_name}")
27
+ home_dir = ftp_dir.nil? ? web_mapper.path : web_mapper.f(ftp_dir).path
28
+
29
+ if (resp = @container_controller.available_validation(name: container_name)).net_status_ok?
30
+ if !File.exists? home_dir
31
+ resp = { error: :logical_error, code: :incorrect_ftp_dir, data: { dir: home_dir.to_s } }
32
+ elsif (resp = self.not_existing_validation(name: name, container_name: container_name)).net_status_ok?
33
+ shell = ftp_only ? '/usr/sbin/nologin' : '/bin/bash'
34
+ if (resp = self._add(name: name, container_name: container_name, home_dir: home_dir, shell: shell)).net_status_ok?
35
+ if generate
36
+ resp = self.passwd(name: name, container_name: container_name, generate: generate)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ resp
42
+ end
13
43
 
44
+ def passwd(name:, container_name:, generate: false)
45
+ if (resp = @container_controller.available_validation(name: container_name)).net_status_ok?
46
+ user_name = "#{container_name}_#{name}"
47
+ passwords = self._create_password(generate: generate)
48
+ self._update_password(name: user_name, encrypted_password: passwords[:encrypted_password])
49
+ generate ? { data: passwords[:password] } : {}
50
+ else
51
+ resp
52
+ end
14
53
  end
15
54
 
16
55
  def delete(name:, container_name:)
56
+ if (resp = @container_controller.available_validation(name: container_name)).net_status_ok? and
57
+ (resp = self.existing_validation(name: name, container_name: container_name)).net_status_ok?
58
+ container_lib_mapper = @lib.containers.f(container_name)
59
+ passwd_mapper = container_lib_mapper.config.f('etc-passwd')
60
+ user_name = "#{container_name}_#{name}"
61
+ self._del(name: user_name)
62
+ passwd_mapper.remove_line!(/^#{user_name}:.*/)
63
+ end
64
+ resp
65
+ end
66
+
67
+ def change(name:, container_name:, ftp_dir: nil, ftp_only: false, generate: false)
68
+ if (resp = self.delete(name: name, container_name: container_name)).net_status_ok?
69
+ self.add(name: name, container_name: container_name, ftp_dir: ftp_dir, ftp_only: ftp_only, generate: generate)
70
+ else
71
+ resp
72
+ end
73
+ end
74
+
75
+ def _get(name:)
76
+ begin
77
+ Etc.getpwnam(name)
78
+ rescue ArgumentError => e
79
+ nil
80
+ end
81
+ end
82
+
83
+ def _add(name:, container_name:, shell: '/usr/sbin/nologin', home_dir: "/web/#{container_name}")
84
+ user = self._get(name: container_name)
85
+ self._add_custom(name: "#{container_name}_#{name}", group: container_name, shell: shell, home_dir: home_dir, uid: user.uid)
86
+ end
87
+
88
+ def _add_system_user(name:, container_name:, shell: '/usr/sbin/nologin', home_dir: "/web/#{container_name}")
89
+ self._add_custom(name: "#{container_name}_#{name}", group: container_name, shell: shell, home_dir: home_dir)
90
+ end
91
+
92
+ def _add_custom(name:, group:, shell: '/usr/sbin/nologin', home_dir: "/web/#{group}", uid: nil)
93
+ if (resp = self.adding_validation(name: name, container_name: group)).net_status_ok?
94
+ container_lib_mapper = @lib.containers.f(group)
95
+ passwd_mapper = container_lib_mapper.config.f('etc-passwd')
96
+
97
+ useradd_command = "useradd #{name} -g #{group} -d #{home_dir} -s #{shell}".split
98
+ useradd_command += "-u #{uid} -o".split unless uid.nil?
99
+ self.command!(useradd_command, debug: false)
100
+
101
+ user = self._get(name: name)
102
+
103
+ self.with_dry_run do |dry_run|
104
+ user_gid, user_uid = dry_run ? ['XXXX', 'XXXX'] : [user.gid, user.uid]
105
+ passwd_mapper.append_line!("#{name}:x:#{user_uid}:#{user_gid}::#{home_dir}:#{shell}")
106
+ end
107
+ end
108
+ resp
109
+ end
110
+
111
+ def _pretty_add_custom(name:, group:, shell: '/usr/sbin/nologin', home_dir: "/web/#{group}", uid: nil)
112
+ self.debug_operation(desc: { code: :user, data: { name: name } }) do |&blk|
113
+ if self._get(name: name)
114
+ blk.call(code: :ok)
115
+ {}
116
+ else
117
+ self._add_custom(name: name, group: group, shell: shell, home_dir: home_dir, uid: uid).tap do
118
+ blk.call(code: :added)
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ def _pretty_del(name:, group:)
125
+ with_adding_group = self._group_get_users(name: group).one? ? true : false
126
+ self._del(name: name)
127
+ self._group_add(name: group) if with_adding_group
128
+ end
129
+
130
+ def _del(name:)
131
+ self.debug_operation(desc: { code: :user, data: { name: name } }) do |&blk|
132
+ self.with_dry_run do |dry_run|
133
+ resp = {}
134
+ resp = self.command!("userdel #{name}", debug: false) unless dry_run
135
+ blk.call(code: :deleted)
136
+ resp
137
+ end
138
+ end
139
+ end
17
140
 
141
+ def _create_password(generate: false)
142
+ password = if generate
143
+ SecureRandom.hex
144
+ else
145
+ while 1
146
+ if (pass = ask('Enter password: ') { |q| q.echo = false }) != ask('Repeat password: ') { |q| q.echo = false }
147
+ self.info('Passwords does not match')
148
+ elsif !StrongPassword::StrengthChecker.new(pass).is_strong?(min_entropy: @config.f('password_strength', default: '15').to_i)
149
+ self.info('Password is weak')
150
+ else
151
+ break
152
+ end
153
+ end
154
+ pass
155
+ end
156
+ encrypted_password = UnixCrypt::SHA512.build(password)
157
+ { password: password, encrypted_password: encrypted_password }
18
158
  end
19
159
 
20
- def change(name:, container_name:, no_ssh: false, no_ftp: false)
160
+ def _update_password(name:, encrypted_password:)
161
+ self.debug_operation(desc: { code: :user, data: { name: name } }) do |&blk|
162
+ self.with_dry_run do |dry_run|
163
+ resp = {}
164
+ resp = self.command!("usermod -p '#{encrypted_password}' #{name}", debug: false) unless dry_run
165
+ blk.call(code: :updated)
166
+ resp
167
+ end
168
+ end
169
+ end
170
+
171
+ def _group_get(name:)
172
+ begin
173
+ Etc.getgrnam(name)
174
+ rescue ArgumentError => e
175
+ nil
176
+ end
177
+ end
178
+
179
+ def _group_add(name:)
180
+ self.debug_operation(desc: { code: :group, data: { name: name } }) do |&blk|
181
+ self.with_dry_run do |dry_run|
182
+ resp = {}
183
+ resp = self.command!("groupadd #{name}", debug: false) unless dry_run
184
+ blk.call(code: :added)
185
+ resp
186
+ end
187
+ end
188
+ end
189
+
190
+ def _group_pretty_add(name:)
191
+ self._group_add(name: name) if self._group_get(name: name).nil?
192
+ end
193
+
194
+ def _group_del(name:)
195
+ self.debug_operation(desc: { code: :group, data: { name: name } }) do |&blk|
196
+ self.with_dry_run do |dry_run|
197
+ resp = {}
198
+ resp = self.command!("groupdel #{name}", debug: false) unless dry_run
199
+ blk.call(code: :deleted)
200
+ resp
201
+ end
202
+ end
203
+ end
204
+
205
+ def _group_pretty_del(name:)
206
+ self._group_del(name: name) unless self._group_get(name: name).nil?
207
+ end
208
+
209
+ def _group_get_users(name:)
210
+ if (group = self._group_get(name: name))
211
+ gid = group.gid
212
+
213
+ users = []
214
+ Etc.passwd do |user|
215
+ users << user if user.gid == gid
216
+ end
217
+ users
218
+ else
219
+ []
220
+ end
221
+ end
222
+
223
+ def _group_get_users_names(name:)
224
+ self._group_get_users(name: name).map(&:name)
225
+ end
226
+
227
+ def _group_get_system_users(name:)
228
+ if (base_user = self._get(name: name))
229
+ self._group_get_users(name: name).map {|u| u.name.slice(/(?<=#{name}_).*/) if u.uid != base_user.uid }.compact
230
+ else
231
+ []
232
+ end
233
+ end
234
+
235
+ def _group_del_users(name:)
236
+ self._group_get_users_names(name: name).each {|user| self._del(name: user) }
237
+ end
238
+
239
+ def adding_validation(name:, container_name:)
240
+ return { error: :input_error, code: :invalid_user_name, data: { name: name, regex: USER_NAME_FORMAT } } if name !~ USER_NAME_FORMAT
241
+ self.not_existing_validation(name: name, container_name: container_name)
242
+ end
243
+
244
+ def existing_validation(name:, container_name:)
245
+ user_name = "#{container_name}_#{name}"
246
+ PathMapper.new('/etc/passwd').check(user_name) ? {} : { error: :logical_error, code: :user_does_not_exists, data: { name: user_name } }
247
+ end
21
248
 
249
+ def not_existing_validation(name:, container_name:)
250
+ self.existing_validation(name: name, container_name: container_name).net_status_ok? ? { error: :logical_error, code: :user_exists, data: { name: "#{container_name}_#{name}" } } : {}
22
251
  end
23
252
  end
24
253
  end