file_sv 0.1.4 → 0.1.8
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.
- checksums.yaml +4 -4
- data/exe/file_sv +3 -1
- data/lib/file_sv/file_processor.rb +2 -1
- data/lib/file_sv/global_settings.rb +29 -1
- data/lib/file_sv/planned_endpoint.rb +1 -1
- data/lib/file_sv/service_loader.rb +3 -1
- data/lib/file_sv/sv_plan.rb +6 -3
- data/lib/file_sv/version.rb +1 -1
- data/lib/file_sv/virtual_server.rb +14 -6
- data/lib/file_sv/yaml_processor.rb +16 -16
- data/lib/file_sv.rb +64 -52
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0b7afdb64abc1410be6cebdcf263fca4f5d6a1bc3319e499aa2465b494ea144
|
4
|
+
data.tar.gz: f64237aecf384cafc4bc9469ebecd6c3e4958083ebad3a1e5e90959b425e2662
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7df5f1b80d1330a08ea6aafa52ba1d4e3d0d01ae963d276ca0a3ad0bffa4f03333e328955e227a86a4d4d980ae9c4a911ee018fea14cbf5d82ceac6baf5c4cdf
|
7
|
+
data.tar.gz: e6d42d44838e2bb3d44bb1427c904dd1a75bbe400b26d882ed4109ebcdd6ceae1c82ebb33333a6efc0114a647a7e861118f851d536b9461c19ee97b83ae93932
|
data/exe/file_sv
CHANGED
@@ -12,10 +12,12 @@ class Exe < Thor
|
|
12
12
|
ServiceLoader.create_plan_for folder
|
13
13
|
end
|
14
14
|
|
15
|
+
option :crt, default: nil, banner: "HTTPS CRT"
|
16
|
+
option :key, default: nil, banner: "HTTPS key"
|
15
17
|
desc "serve folder", "Serve virtual service based on folder"
|
16
18
|
def serve(folder)
|
17
19
|
plan folder
|
18
|
-
ServiceLoader.serve_plan
|
20
|
+
ServiceLoader.serve_plan options
|
19
21
|
end
|
20
22
|
|
21
23
|
desc "inspect folder", "Inspect details of what's served at folder"
|
@@ -6,7 +6,8 @@ class FileProcessor
|
|
6
6
|
class << self
|
7
7
|
# Process file, adding it to plan
|
8
8
|
def process(filename)
|
9
|
-
|
9
|
+
endpoint = PlannedEndpoint.new(filename)
|
10
|
+
SvPlan + endpoint unless GlobalSettings.ignored_status? endpoint.status_code
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
@@ -6,7 +6,11 @@ class GlobalSettings
|
|
6
6
|
|
7
7
|
@empty_body_status = 204
|
8
8
|
|
9
|
-
@ignore_files = "{*.md,Dockerfile
|
9
|
+
@ignore_files = "{*.md,Dockerfile}"
|
10
|
+
|
11
|
+
@https = false
|
12
|
+
|
13
|
+
@ignore_status_codes = nil
|
10
14
|
class << self
|
11
15
|
# @return [String] Default REST method when none specified by filename
|
12
16
|
attr_accessor :default_method
|
@@ -14,9 +18,33 @@ class GlobalSettings
|
|
14
18
|
attr_accessor :empty_body_status
|
15
19
|
# @return [Array] Expression representing files to ignore
|
16
20
|
attr_accessor :ignore_files
|
21
|
+
# @return [Boolean] Whether to serve https using self signed certificate. Deprecated now
|
22
|
+
attr_accessor :https
|
23
|
+
# @return [String] Path to HTTPS cert
|
24
|
+
attr_accessor :cert
|
25
|
+
# @return [String] Path to HTTPS key
|
26
|
+
attr_accessor :key
|
27
|
+
# @return [Array] List of http status codes to ignore
|
28
|
+
attr_accessor :ignore_status_codes
|
29
|
+
|
30
|
+
# @param [Integer] status_code HTTP status code
|
31
|
+
# @return [Boolean] Whether status code is currently ignored
|
32
|
+
def ignored_status?(status_code)
|
33
|
+
return unless ignore_status_codes
|
34
|
+
|
35
|
+
ignore_status_codes.split(",").each do |code|
|
36
|
+
regex = Regexp.new code.to_s
|
37
|
+
result = status_code.to_s[regex]
|
38
|
+
next unless result
|
39
|
+
|
40
|
+
return true unless result.empty?
|
41
|
+
end
|
42
|
+
false
|
43
|
+
end
|
17
44
|
end
|
18
45
|
end
|
19
46
|
|
47
|
+
# Http settings that all HTTP method types inherit
|
20
48
|
module CommonHttpSettings
|
21
49
|
attr_accessor :default_status
|
22
50
|
end
|
@@ -19,9 +19,11 @@ module ServiceLoader
|
|
19
19
|
end
|
20
20
|
|
21
21
|
# Serve plan
|
22
|
-
def serve_plan
|
22
|
+
def serve_plan(thor_options)
|
23
23
|
require "sinatra"
|
24
24
|
require_relative "virtual_server"
|
25
|
+
GlobalSettings.key = thor_options[:key] if thor_options[:key]
|
26
|
+
GlobalSettings.cert = thor_options[:crt] if thor_options[:crt]
|
25
27
|
VirtualServer.run!
|
26
28
|
end
|
27
29
|
end
|
data/lib/file_sv/sv_plan.rb
CHANGED
@@ -15,8 +15,11 @@ class SvPlan
|
|
15
15
|
def create(folder)
|
16
16
|
self.serving_folder = folder
|
17
17
|
puts "Creating service based on files in #{folder}"
|
18
|
-
file_list = Dir.glob("#{folder}/**/*.*") - Dir.glob(GlobalSettings.ignore_files)
|
19
|
-
file_list.each
|
18
|
+
file_list = Dir.glob("#{folder}/**/*.*", File::FNM_DOTMATCH) - Dir.glob("#{folder}/#{GlobalSettings.ignore_files}, File::FNM_DOTMATCH")
|
19
|
+
file_list.each do |file|
|
20
|
+
next if File.directory? file
|
21
|
+
process_file file
|
22
|
+
end
|
20
23
|
end
|
21
24
|
|
22
25
|
# Process file, for the most part creating endpoint.method from it
|
@@ -34,7 +37,7 @@ class SvPlan
|
|
34
37
|
# Show plan
|
35
38
|
def show
|
36
39
|
endpoint_desc = ""
|
37
|
-
endpoints.sort { |a, b| a[0].
|
40
|
+
endpoints.sort { |a, b| a[0].casecmp b[0] }.each do |endpoint, methods|
|
38
41
|
endpoint_desc += "#{endpoint} \n"
|
39
42
|
methods.each do |method_name, endpoints|
|
40
43
|
endpoint_desc += description_message method_name, endpoints
|
data/lib/file_sv/version.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "puma"
|
4
4
|
require "sinatra"
|
5
5
|
require "docdsl"
|
6
|
+
require "openssl"
|
6
7
|
|
7
8
|
# Virtual server hosting virtual service defined through files
|
8
9
|
class VirtualServer < Sinatra::Base
|
9
|
-
set :server,
|
10
|
+
set :server, :puma
|
11
|
+
enable :logging if ENV['debug'] == "true"
|
10
12
|
set :bind, "0.0.0.0"
|
11
13
|
|
12
14
|
register Sinatra::DocDsl
|
@@ -32,11 +34,13 @@ for more details'
|
|
32
34
|
|
33
35
|
# Log endpoint. Return content and status code defined by endpoint
|
34
36
|
# @param [PlannedEndpoint] endpoint Planned endpoint to serve
|
35
|
-
def serve(endpoint, id = nil)
|
36
|
-
message = "Using endpoint based on file #{endpoint.serving_file_name}."
|
37
|
+
def serve(endpoint, id = nil)
|
37
38
|
@id = id
|
38
|
-
|
39
|
-
|
39
|
+
if ENV['debug'] == "true"
|
40
|
+
message = "Using endpoint based on file #{endpoint.serving_file_name}."
|
41
|
+
message += " Using param '#{@id}'" if id
|
42
|
+
puts message
|
43
|
+
end
|
40
44
|
[endpoint.status_code, output_for(endpoint, binding)]
|
41
45
|
end
|
42
46
|
|
@@ -49,11 +53,15 @@ for more details'
|
|
49
53
|
if endpoint_base.path.include? "#{File::Separator}:"
|
50
54
|
send(endpoint_base.method, endpoint_base.path) do |id|
|
51
55
|
endpoint = endpoints.sample
|
56
|
+
@params = params
|
57
|
+
puts "#{endpoint_base.method} #{endpoint_base.path} ?#{@params}"
|
52
58
|
serve endpoint, id
|
53
59
|
end
|
54
60
|
else
|
55
61
|
send(endpoint_base.method, endpoint_base.path) do
|
56
62
|
endpoint = endpoints.sample
|
63
|
+
@params = params
|
64
|
+
puts "#{endpoint_base.method} #{endpoint_base.path} ?#{@params}" unless ENV['ignore_path'] && ("/#{ENV['ignore_path']}" == endpoint_base.path)
|
57
65
|
serve endpoint
|
58
66
|
end
|
59
67
|
end
|
@@ -1,16 +1,16 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Process YAML files
|
4
|
-
class YamlProcessor
|
5
|
-
class << self
|
6
|
-
# Process YAML file
|
7
|
-
def process(filename)
|
8
|
-
if filename == "/file_sv.yaml"
|
9
|
-
puts "Overriding default config based on #{File.join(Dir.pwd, filename[1
|
10
|
-
load_default_config filename[1
|
11
|
-
else
|
12
|
-
puts "Skipping #{filename}"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Process YAML files
|
4
|
+
class YamlProcessor
|
5
|
+
class << self
|
6
|
+
# Process YAML file
|
7
|
+
def process(filename)
|
8
|
+
if filename == "/file_sv.yaml"
|
9
|
+
puts "Overriding default config based on #{File.join(Dir.pwd, filename[1..])}"
|
10
|
+
load_default_config filename[1..]
|
11
|
+
else
|
12
|
+
puts "Skipping #{filename}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/file_sv.rb
CHANGED
@@ -1,52 +1,64 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "yaml"
|
4
|
-
require_relative "file_sv/version"
|
5
|
-
require_relative "file_sv/global_settings"
|
6
|
-
require_relative "file_sv/sv_plan"
|
7
|
-
require_relative "file_sv/service_loader"
|
8
|
-
require_relative "file_sv/planned_endpoint"
|
9
|
-
|
10
|
-
# Create Service Virtualization from a simple file system
|
11
|
-
module FileSv
|
12
|
-
# General error for FileSv
|
13
|
-
class Error < StandardError; end
|
14
|
-
|
15
|
-
# Error related to incorrect format of filename
|
16
|
-
class FileNameError < Error; end
|
17
|
-
|
18
|
-
class << self
|
19
|
-
# @return [Hash] Mapping of REST method names to setting classes
|
20
|
-
def rest_methods
|
21
|
-
{
|
22
|
-
get: GetSettings, post: PostSettings, patch: PatchSettings, options: OptionsSettings,
|
23
|
-
delete: DeleteSettings, put: PutSettings
|
24
|
-
}
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
CONFIG_FILE = "file_sv.yaml"
|
30
|
-
|
31
|
-
# Set values in global settings based on config
|
32
|
-
def load_default_config(file_path)
|
33
|
-
return unless File.exist? file_path
|
34
|
-
|
35
|
-
config = YAML.load_file file_path
|
36
|
-
return unless config # Handle empty YAML file
|
37
|
-
|
38
|
-
config["global"]&.each do |key, value|
|
39
|
-
GlobalSettings.send("#{key}=", value)
|
40
|
-
end
|
41
|
-
|
42
|
-
load_rest_method_config config
|
43
|
-
end
|
44
|
-
|
45
|
-
# Load details of each REST method
|
46
|
-
def load_rest_method_config(config)
|
47
|
-
FileSv.rest_methods.each do |method, setting_class|
|
48
|
-
config[method.to_s]&.each { |key, value| setting_class.send("#{key}=", value) }
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
require_relative "file_sv/version"
|
5
|
+
require_relative "file_sv/global_settings"
|
6
|
+
require_relative "file_sv/sv_plan"
|
7
|
+
require_relative "file_sv/service_loader"
|
8
|
+
require_relative "file_sv/planned_endpoint"
|
9
|
+
|
10
|
+
# Create Service Virtualization from a simple file system
|
11
|
+
module FileSv
|
12
|
+
# General error for FileSv
|
13
|
+
class Error < StandardError; end
|
14
|
+
|
15
|
+
# Error related to incorrect format of filename
|
16
|
+
class FileNameError < Error; end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
# @return [Hash] Mapping of REST method names to setting classes
|
20
|
+
def rest_methods
|
21
|
+
{
|
22
|
+
get: GetSettings, post: PostSettings, patch: PatchSettings, options: OptionsSettings,
|
23
|
+
delete: DeleteSettings, put: PutSettings
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
CONFIG_FILE = "file_sv.yaml"
|
30
|
+
|
31
|
+
# Set values in global settings based on config
|
32
|
+
def load_default_config(file_path)
|
33
|
+
return unless File.exist? file_path
|
34
|
+
|
35
|
+
config = YAML.load_file file_path
|
36
|
+
return unless config # Handle empty YAML file
|
37
|
+
|
38
|
+
config["global"]&.each do |key, value|
|
39
|
+
GlobalSettings.send("#{key}=", value)
|
40
|
+
end
|
41
|
+
|
42
|
+
load_rest_method_config config
|
43
|
+
end
|
44
|
+
|
45
|
+
# Load details of each REST method
|
46
|
+
def load_rest_method_config(config)
|
47
|
+
FileSv.rest_methods.each do |method, setting_class|
|
48
|
+
config[method.to_s]&.each { |key, value| setting_class.send("#{key}=", value) }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Set global params based on ENV vars
|
53
|
+
def set_based_on_env_vars
|
54
|
+
GlobalSettings.instance_variables.each do |setting|
|
55
|
+
setting_name = setting.to_s[1..]
|
56
|
+
if ENV[setting_name]
|
57
|
+
puts "Setting #{setting_name} to #{ENV[setting_name]}"
|
58
|
+
GlobalSettings.send("#{setting_name}=", ENV[setting_name])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
load_default_config CONFIG_FILE
|
64
|
+
set_based_on_env_vars
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: file_sv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Garratt
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faker
|
@@ -67,19 +67,19 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: puma
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: '0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: '0'
|
83
83
|
description: |-
|
84
84
|
Create a virtual REST service through file structure. Customize it more
|
85
85
|
through ERB and special file names
|
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
requirements: []
|
127
|
-
rubygems_version: 3.2.
|
127
|
+
rubygems_version: 3.2.32
|
128
128
|
signing_key:
|
129
129
|
specification_version: 4
|
130
130
|
summary: REST service virtualisation through file structure.
|