Projects
home:rottame:vhosts-ng
rubygem-nginx-controller
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 12
View file
rubygem-nginx-controller.changes
Changed
@@ -1,4 +1,19 @@ ------------------------------------------------------------------- +Fri Oct 31 07:53:29 UTC 2025 - Angelo Grossini <angelo@intercom.it> + +- feat(service): Enhance Nginx configuration with access control and logging + - Add support for writing and deleting password files for access rules + - Create necessary directories in Dockerfile for SSL and logging + - Update Nginx configuration template to handle access rules dynamically + - Implement integration tests for service configuration generation and validation + +- feat(service): Implement access rules parsing and location sorting + - Add access_rules method to decode and parse Base64 encoded access rules + - Normalize location paths by ensuring leading and trailing slashes are handled + - Introduce locations method to generate a sorted list of unique locations + - Remove unused auth_basic method code for clarity + +------------------------------------------------------------------- Tue Sep 5 15:58:46 UTC 2023 - Angelo Grossini <rottame@intercom.it> - remove tasks filter, prevent reload of all services
View file
rubygem-nginx-controller.spec
Changed
@@ -1,7 +1,7 @@ %define mod_name nginx-controller %define mod_full_name %{mod_name}-%{version} Name: rubygem-nginx-controller -Version: 2.0.4 +Version: 2.1.0 Release: 0 Summary: vhng nginx controller License: Apache-2.0
View file
nginx-controller-2.0.4.gem/checksums.yaml.gz -> nginx-controller-2.1.0.gem/checksums.yaml.gz
Changed
@@ -1,7 +1,7 @@ --- SHA256: - metadata.gz: e19cd600417822d9cf8ac415314440ac257c99e8479016cfb18b4166b000d91c - data.tar.gz: 6910073cc9c65fe184b1232af12b4ae5f1712a863aac40126ae6ddcf186063fe + metadata.gz: 3cc6fb3509f1ad64d347a48bb24f31cd8d58b88b6db2786046268086609f2998 + data.tar.gz: 8fdfb3f606b712f3c897ec23b8f8a57b1e73112fb75e17d6238451a50e0307c3 SHA512: - metadata.gz: 96ebeaaf9a0ae45d866ba81ab47de0f7a1c726a6dda3f235894240e9458e47dbbb476bc19c3c063a9f5137a49ec0eabb1bb661c7a62077c583a86355139185e5 - data.tar.gz: 66498186617a42cacd5aa4ed5746b9af1c9eeec2a1838062aa9bcc8d9a86a719aa21d59c613fcfe84da49ab51f1ede376900f812ec89fea2ca7f11649ea3a357 + metadata.gz: 99835d331f2a1c2eeadf86088443eff61d35925e59abfc5930ddc3fc4340dd8b900495e1351a546b032d539fadfebb3709cfa7a6851bf719dfd8bb674a100df0 + data.tar.gz: a93827cc17e03024ed3414e42dd240362c16ddea37dabe24f2383d0187360f87cfa750d54b894239c68a212abc2f184e9b0eaf6a5f4370578f33b8eb45040bcd
View file
nginx-controller-2.0.4.gem/data/lib/nginx_controller/docker/service.rb -> nginx-controller-2.1.0.gem/data/lib/nginx_controller/docker/service.rb
Changed
@@ -5,6 +5,7 @@ require 'date' require 'fileutils' require 'openssl' +require 'base64' require 'active_support/all' require 'nginx_controller/base_service' require 'nginx_controller/self_signed_cert' @@ -107,6 +108,7 @@ def configure! create_directories + write_passwd! super if rotate_logs? config = render_logrotate @@ -115,6 +117,7 @@ end def deconfigure! + delete_passwd! super if File.exists?(logrotate_config_filename) FileUtils.rm_f(logrotate_config_filename) @@ -197,28 +200,55 @@ labels'vhosts-ng/service/access-log' || (raise StandardError.new("#{self.name}: access log not defined")) end - def auth_basic - @auth_basic ||= begin - count = 1 - auths = labels.select{|l| l =~ /vhosts-ng\/auth\/basic/}.map { | k, v | - loc = k.gsub(/vhosts-ng\/auth\/basic/, '') - secret, realm = v.split(',', 2) - secret = File::expand_path(secret, '/') # sanitize.... - secret = File.join(NginxController.htpasswd_path, service_name, secret) - unless File.exists?(secret) - # generate a dummy htpasswd with a random username/password - secret = File.join(NginxController.htpasswd_path, "dummy", service_name, "htpasswd.#{count}") - FileUtils.mkdir_p(File.dirname(secret)) - File.open(secret, 'wb+') do | f | - f.write "%s:%s" % - SecureRandom.alphanumeric(8), - SecureRandom.alphanumeric(16).crypt("$5$#{SecureRandom.alphanumeric(8)}$"), - + def access_rules + @access_rules ||= begin + pairs = labels.select { |k, _| k =~ /\Avhosts-ng\/http\/access-rules/ }.map { |_, v| + begin + raw = Base64.strict_decode64(v) + data = JSON.parse(raw, symbolize_names: true) + loc = data:location.to_s.strip + + # normalize leading and trailing slashes + unless loc.blank? + loc = "/#{loc}" unless loc.start_with?('/') + loc = loc.chomp('/') if loc.length > 1 && loc.end_with?('/') end + + next if loc.blank? + next unless data:allow || data:deny || data:auth + + rule = { + location: loc, + allow: data:allow ? Array(data:allow) : nil, + deny: !data:allow && data:deny ? Array(data:deny) : nil, + auth: data:auth ? Array(data:auth) : nil, + } + loc, rule + rescue + nil + end + }.compact + Hashpairs + end + end + + def locations + @locations = if access_rules.any? + locs = '/' + access_rules.keys + locs = locs.uniq + without_root = locs.reject { |p| p == '/' } + sorted = without_root.sort do |a, b| + a_segments = a.split('/').reject(&:blank?).length + b_segments = b.split('/').reject(&:blank?).length + if a_segments != b_segments + b_segments <=> a_segments # deeper (child) first + else + a <=> b end - loc, {location: loc, secret: secret, realm: realm || 'Pretected area'} - } - auths = Hashauths + end + sorted + '/' + else + '/' end end @@ -315,7 +345,7 @@ if ssl? @ssl_certs_list ||= begin list = - + certs = labels.select{|k,v| k =~ /\Avhosts-ng\/ssl\/certs\/.*\Z/} certs.each do | id, d | id = File::basename(id) # LAZY but works @@ -337,7 +367,7 @@ key: acme.privkey_path, }) end - + list << OpenStruct.new({ names: self_signed_cert.names, cert: self_signed_cert.cert_path, @@ -377,6 +407,25 @@ memo end end + + def write_passwd! + cnt = 0 + access_rules.each do | k, ar | + if ar:auth && ar:auth.any? + passwd = File.join('/etc/nginx/vhosts.d/', "#{name}.#{cnt}.passwd") + File.open(passwd, 'wb+') {|f| f.write(ar:auth.join("\n"))} + ar:passwd = passwd + cnt += 1 + end + end + end + + def delete_passwd! + glob = File.join('/etc/nginx/vhosts.d/', "#{name}.*.passwd") + Dirglob.each do | passwd | + File.delete(passwd) + end + end end end end
View file
nginx-controller-2.0.4.gem/data/lib/nginx_controller/templates/nginx-common.erb -> nginx-controller-2.1.0.gem/data/lib/nginx_controller/templates/nginx-common.erb
Changed
@@ -17,20 +17,36 @@ client_max_body_size <%= max_body_size %>; <% end -%> - location / { <% if running? -%> -<% if auth_basic'/' -%> - auth_basic "<%= auth_basic'/':realm %>"; - auth_basic_user_file <%= auth_basic'/':secret %>; - +<% locations.each do | loc | -%> + <% access = access_rulesloc -%> + + location <%= loc %> { +<% if access -%> +<% if access:passwd -%> + auth_basic "Restricted area"; + auth_basic_user_file <%= access:passwd %>; +<% end -%> +<% if access:allow -%> +<% access:allow.each do |ip| %> + allow <%= ip %>; +<% end -%> + deny all; +<% elsif access:deny -%> +<% access:deny.each do |ip| -%> + deny <%= ip -%>; +<% end -%> <% end -%> +<% end -%> + recursive_error_pages on; if ($http_upgrade) { return 418; } -<%= render 'nginx-proxy-block'%> +<%= render 'nginx-proxy-block', {location: loc} %> } +<% end -%> location @websocket { proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; @@ -58,19 +74,9 @@ proxy_read_timeout 86400s; proxy_connect_timeout 10s; proxy_send_timeout 30s; + } <% else -%> + location / { return 403; -<% end -%> - } -<% if running? -%> - <% auth_basic.each do | loc, data | -%> - <% next if loc == '/' %> - - location <%= loc %> { - auth_basic "<%= data:realm %>"; - auth_basic_user_file <%= data:secret %>; - -<%= render 'nginx-proxy-block', {location: loc} %> } - <% end -%> -<% end -%> \ No newline at end of file +<% end -%>
View file
nginx-controller-2.0.4.gem/metadata.gz -> nginx-controller-2.1.0.gem/metadata.gz
Changed
@@ -1,16 +1,30 @@ --- !ruby/object:Gem::Specification name: nginx-controller version: !ruby/object:Gem::Version - version: 2.0.4 + version: 2.1.0 platform: ruby authors: - Angelo Grossini autorequire: bindir: bin cert_chain: -date: 2023-09-05 00:00:00.000000000 Z +date: 2025-10-31 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency + name: rspec + requirement: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.12' + type: :development + prerelease: false + version_requirements: !ruby/object:Gem::Requirement + requirements: + - - "~>" + - !ruby/object:Gem::Version + version: '3.12' +- !ruby/object:Gem::Dependency name: eventmachine requirement: !ruby/object:Gem::Requirement requirements: @@ -126,7 +140,7 @@ - !ruby/object:Gem::Version version: '0' requirements: -rubygems_version: 3.3.15 +rubygems_version: 3.5.22 signing_key: specification_version: 4 summary: Nginx controller for vhosts-ng
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.