kashi 0.1.0.beta1 → 0.1.0
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/README.md +36 -18
- data/lib/kashi/cli.rb +9 -0
- data/lib/kashi/client.rb +6 -2
- data/lib/kashi/client_wrapper.rb +10 -3
- data/lib/kashi/dsl/test.rb +19 -1
- data/lib/kashi/filterable.rb +20 -0
- data/lib/kashi/secret_expander.rb +76 -0
- data/lib/kashi/version.rb +1 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7331c135793bad57b313139dcfc55669b67e7bf
|
4
|
+
data.tar.gz: f561bf7f18a29b38e489e042d453c68eddc9eeac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee5c53b2caf18c8d20fc33923d816bc7e9e6522472e036a0927db96c38a3ffddb729951f33c3921dcaaf60587cbf21316cbba8d594908cd97b79bfe51260efc2
|
7
|
+
data.tar.gz: a84b8e6ddb0fdae169065da94478e8db78ccd3a05892bb5cc4129f042b484ec463a4808c01b51903d38f5d651ad1982c5f367e1f1099ae373b82240a90e9add5
|
data/README.md
CHANGED
@@ -39,10 +39,14 @@ Usage: kashi [options]
|
|
39
39
|
-n, --dry-run Dry run
|
40
40
|
--no-color
|
41
41
|
No color
|
42
|
+
--secret-provider NAME
|
43
|
+
use secret value expansion
|
42
44
|
-s, --split Split export DLS file contact group and tests
|
43
45
|
--split-more
|
44
46
|
Split export DLS file to 1 per object
|
45
47
|
-v, --debug Show debug log
|
48
|
+
-i, --include-names NAMES include website_name
|
49
|
+
-x, --exclude-names NAMES exclude website_name by regex
|
46
50
|
```
|
47
51
|
|
48
52
|
## SCfile
|
@@ -67,42 +71,56 @@ cake do
|
|
67
71
|
end
|
68
72
|
|
69
73
|
test do
|
74
|
+
paused 0
|
75
|
+
|
76
|
+
test_type "HTTP"
|
77
|
+
|
78
|
+
# Required Details
|
70
79
|
website_name "your awesome site"
|
71
80
|
website_url "https://example.com/healthcheck"
|
72
81
|
|
73
|
-
paused 0
|
74
|
-
# HTTP,TCP,PING
|
75
|
-
test_type "HTTP"
|
76
82
|
contact_group ["Alarm"]
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
83
|
+
|
84
|
+
# Scans
|
85
|
+
enable_ssl_warning 1
|
86
|
+
|
87
|
+
# HTTP Communication Options
|
81
88
|
find_string ""
|
82
89
|
do_not_find 0
|
83
|
-
|
84
|
-
|
90
|
+
follow_redirect 1
|
85
91
|
custom_header(
|
86
92
|
{"Host"=>"example.com"}
|
87
93
|
)
|
88
|
-
|
94
|
+
status_codes ["204", "205", "206", "303", "400", "401", "403", "404", "405", "406", "408", "410", "413", "444", "429", "494", "495", "496", "499", "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", "510", "511", "521", "522", "523", "524", "520", "598", "599", "302"]
|
89
95
|
|
90
|
-
|
91
|
-
basic_pass nil
|
96
|
+
logo_image ""
|
92
97
|
|
93
|
-
|
98
|
+
# Test Locations
|
99
|
+
node_locations ["freeserver11"]
|
94
100
|
|
95
|
-
|
96
|
-
dns_server ""
|
101
|
+
# Threshold Control
|
97
102
|
trigger_rate "0"
|
103
|
+
confirmation "2"
|
104
|
+
|
105
|
+
# Additional Options
|
106
|
+
check_rate 300
|
107
|
+
timeout 40
|
98
108
|
test_tags ["Web", "Internal"]
|
99
|
-
|
100
|
-
enable_ssl_warning 0
|
101
|
-
follow_redirect 1
|
109
|
+
website_host ""
|
102
110
|
end
|
103
111
|
end
|
104
112
|
```
|
105
113
|
|
114
|
+
## Secret provider
|
115
|
+
|
116
|
+
If you don't want to commit your Basic authentication password, you can use SecretProvider.
|
117
|
+
Use --secret-provider option to select provider.(e.g. --secret-provider=vault) Expression inside ${...} is passed to provider.
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
basic_user "username"
|
121
|
+
basic_pass "${password}"
|
122
|
+
```
|
123
|
+
|
106
124
|
## Similar tools
|
107
125
|
|
108
126
|
* [Codenize.tools](http://codenize.tools/)
|
data/lib/kashi/cli.rb
CHANGED
@@ -13,6 +13,8 @@ module Kashi
|
|
13
13
|
@filepath = 'SCfile'
|
14
14
|
@options = {
|
15
15
|
color: true,
|
16
|
+
includes: [],
|
17
|
+
excludes: [],
|
16
18
|
}
|
17
19
|
parser.order!(@argv)
|
18
20
|
end
|
@@ -37,9 +39,16 @@ module Kashi
|
|
37
39
|
opts.on('-e', '--export', 'Export to DSL') { @export = true }
|
38
40
|
opts.on('-n', '--dry-run', 'Dry run') { @options[:dry_run] = true }
|
39
41
|
opts.on('', '--no-color', 'No color') { @options[:color] = false }
|
42
|
+
opts.on('', '--secret-provider NAME', 'use secret value expansion') { |v| @options[:secret_provider] = v }
|
40
43
|
opts.on('-s', '--split', 'Split export DLS file contact group and tests') { @options[:split] = true }
|
41
44
|
opts.on('', '--split-more', 'Split export DLS file to 1 per object') { @options[:split_more] = true }
|
42
45
|
opts.on('-v', '--debug', 'Show debug log') { Kashi.logger.level = Logger::DEBUG }
|
46
|
+
opts.on('-i', '--include-names NAMES', 'include website_name', Array) { |v| @options[:includes] = v }
|
47
|
+
opts.on('-x', '--exclude-names NAMES', 'exclude website_name by regex', Array) do |v|
|
48
|
+
@options[:excludes] = v.map! do |name|
|
49
|
+
name =~ /\A\/(.*)\/\z/ ? Regexp.new($1) : Regexp.new("\A#{Regexp.escape(name)}\z")
|
50
|
+
end
|
51
|
+
end
|
43
52
|
end
|
44
53
|
end
|
45
54
|
|
data/lib/kashi/client.rb
CHANGED
@@ -3,9 +3,11 @@ require 'kashi'
|
|
3
3
|
require 'kashi/converter'
|
4
4
|
require 'kashi/client_wrapper'
|
5
5
|
require 'kashi/dsl'
|
6
|
+
require 'kashi/filterable'
|
6
7
|
|
7
8
|
module Kashi
|
8
9
|
class Client
|
10
|
+
include Filterable
|
9
11
|
MAGIC_COMMENT = <<-EOS
|
10
12
|
# -*- mode: ruby -*-
|
11
13
|
# vi: set ft=ruby :
|
@@ -14,6 +16,7 @@ module Kashi
|
|
14
16
|
def initialize(filepath, options = {})
|
15
17
|
@filepath = filepath
|
16
18
|
@options = options
|
19
|
+
@options[:secret_expander] = SecretExpander.new(@options[:secret_provider]) if @options[:secret_provider]
|
17
20
|
end
|
18
21
|
|
19
22
|
def traverse_contact_groups(dsl_contact_groups, sc_contact_groups_by_id, sc_contact_groups_by_name)
|
@@ -52,8 +55,9 @@ module Kashi
|
|
52
55
|
end
|
53
56
|
|
54
57
|
def traverse_tests(dsl_tests, sc_tests_by_id, sc_tests_by_name)
|
55
|
-
|
56
|
-
|
58
|
+
dsl_target_tests = dsl_tests.select { |t| target?(t.website_name) }
|
59
|
+
dsl_tests_by_name = dsl_target_tests.group_by(&:website_name)
|
60
|
+
dsl_tests_by_id = dsl_target_tests.group_by(&:test_id)
|
57
61
|
|
58
62
|
# create
|
59
63
|
dsl_tests_by_name.reject { |n, _| sc_tests_by_name[n] }.each do |name, dsl_tests|
|
data/lib/kashi/client_wrapper.rb
CHANGED
@@ -1,17 +1,24 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
require 'statuscake'
|
3
|
+
require 'kashi/filterable'
|
3
4
|
|
4
5
|
module Kashi
|
5
6
|
class ClientWrapper
|
6
7
|
extend Forwardable
|
8
|
+
include Filterable
|
7
9
|
|
8
|
-
def_delegators :@client, *%i
|
10
|
+
def_delegators :@client, *%i(
|
9
11
|
contactgroups contactgroups_update
|
10
|
-
|
11
|
-
|
12
|
+
tests_details tests_update
|
13
|
+
)
|
12
14
|
|
13
15
|
def initialize(options)
|
14
16
|
@client = StatusCake::Client.new(API: ENV['KASHI_SC_API_KEY'], Username: ENV['KASHI_SC_USER'])
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
def tests
|
21
|
+
@client.tests.select { |t| target?(t['WebsiteName']) }
|
15
22
|
end
|
16
23
|
end
|
17
24
|
end
|
data/lib/kashi/dsl/test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ostruct'
|
2
|
+
require 'kashi/secret_expander'
|
2
3
|
|
3
4
|
module Kashi
|
4
5
|
class DSL
|
@@ -8,17 +9,20 @@ module Kashi
|
|
8
9
|
TestID Paused WebsiteName WebsiteURL Port NodeLocations Timeout CustomHeader Confirmation CheckRate
|
9
10
|
DNSServer DNSIP BasicUser BasicPass LogoImage UseJar WebsiteHost Virus FindString DoNotFind
|
10
11
|
TestType ContactGroup TriggerRate TestTags StatusCodes EnableSSLWarning FollowRedirect
|
12
|
+
PostRaw FinalEndpoint
|
11
13
|
/ # PingURL RealBrowser Public Branding
|
12
14
|
ATTRIBUTES = %i/
|
13
15
|
test_id paused website_name website_url port node_locations timeout custom_header confirmation check_rate
|
14
16
|
dns_server dns_ip basic_user basic_pass logo_image use_jar website_host virus find_string do_not_find
|
15
17
|
test_type contact_group trigger_rate test_tags status_codes enable_ssl_warning follow_redirect
|
18
|
+
post_raw final_endpoint
|
16
19
|
/ # ping_url real_browser public branding
|
17
20
|
attr_accessor *ATTRIBUTES
|
18
21
|
|
19
22
|
def initialize(context)
|
20
23
|
@context = context
|
21
24
|
@options = context.options
|
25
|
+
@options[:secret_expander] = SecretExpander.new(@options[:secret_provider]) if @options[:secret_provider]
|
22
26
|
end
|
23
27
|
|
24
28
|
def to_h
|
@@ -101,13 +105,23 @@ module Kashi
|
|
101
105
|
def modify
|
102
106
|
return unless updated?
|
103
107
|
Kashi.logger.info("Modify Test `#{website_name}` #{test_id}")
|
104
|
-
|
108
|
+
masked_dsl_has = dsl_hash.dup.tap { |h| h[:basic_pass] = '****' }
|
109
|
+
Kashi.logger.info("<diff>\n#{Kashi::Utils.diff(sc_hash, masked_dsl_has, color: @options[:color])}")
|
105
110
|
Kashi.logger.debug(modify_params)
|
106
111
|
return if @options[:dry_run]
|
107
112
|
|
108
113
|
client.tests_update(modify_params)
|
109
114
|
end
|
110
115
|
|
116
|
+
def basic_pass
|
117
|
+
secret_expander = @options[:secret_expander]
|
118
|
+
if secret_expander
|
119
|
+
secret_expander.expand(@basic_pass)
|
120
|
+
else
|
121
|
+
@basic_pass
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
111
125
|
def client
|
112
126
|
@client ||= ClientWrapper.new(@options)
|
113
127
|
end
|
@@ -139,6 +153,10 @@ module Kashi
|
|
139
153
|
@result.status_codes = []
|
140
154
|
@result.virus = ''
|
141
155
|
|
156
|
+
# not used
|
157
|
+
@result.post_raw = ''
|
158
|
+
@result.final_endpoint = ''
|
159
|
+
|
142
160
|
instance_eval(&block)
|
143
161
|
end
|
144
162
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Kashi
|
2
|
+
module Filterable
|
3
|
+
def target?(website_name)
|
4
|
+
unless @options[:includes].empty?
|
5
|
+
unless @options[:includes].include?(website_name)
|
6
|
+
Kashi.logger.debug("skip website_name(with include-names option) #{website_name}")
|
7
|
+
return false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
unless @options[:excludes].empty?
|
12
|
+
if @options[:excludes].any? { |regex| website_name =~ regex }
|
13
|
+
Kashi.logger.debug("skip website_name(with exclude-names option) #{website_name}")
|
14
|
+
return false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
module Kashi
|
4
|
+
class ExpansionError < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class SecretExpander
|
8
|
+
Literal = Struct.new(:literal)
|
9
|
+
Variable = Struct.new(:name)
|
10
|
+
|
11
|
+
def initialize(provider_name)
|
12
|
+
@provider = load_provider(provider_name)
|
13
|
+
@asked_variables = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def expand(str)
|
17
|
+
return str unless str
|
18
|
+
tokens = parse(str)
|
19
|
+
variables = Set.new
|
20
|
+
tokens.each do |token|
|
21
|
+
if token.is_a?(Variable)
|
22
|
+
unless @asked_variables.include?(token.name)
|
23
|
+
variables << token.name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
unless variables.empty?
|
29
|
+
@provider.ask(variables).each do |k, v|
|
30
|
+
@asked_variables[k] = v
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
tokens.map do |token|
|
35
|
+
case token
|
36
|
+
when Literal
|
37
|
+
token.literal
|
38
|
+
when Variable
|
39
|
+
@asked_variables.fetch(token.name)
|
40
|
+
else
|
41
|
+
raise ExpansionError.new("Unknown token type: #{token.class}")
|
42
|
+
end
|
43
|
+
end.join
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def parse(value)
|
49
|
+
s = StringScanner.new(value)
|
50
|
+
tokens = []
|
51
|
+
pos = 0
|
52
|
+
while s.scan_until(/\$\{(.*?)\}/)
|
53
|
+
pre = s.string.byteslice(pos...(s.pos - s.matched.size))
|
54
|
+
var = s[1]
|
55
|
+
unless pre.empty?
|
56
|
+
tokens << Literal.new(pre)
|
57
|
+
end
|
58
|
+
if var.empty?
|
59
|
+
raise ExpansionError.new('Empty interpolation is not allowed')
|
60
|
+
else
|
61
|
+
tokens << Variable.new(var)
|
62
|
+
end
|
63
|
+
pos = s.pos
|
64
|
+
end
|
65
|
+
unless s.rest.empty?
|
66
|
+
tokens << Literal.new(s.rest)
|
67
|
+
end
|
68
|
+
tokens
|
69
|
+
end
|
70
|
+
|
71
|
+
def load_provider(name)
|
72
|
+
require "kashi/secret_providers/#{name}"
|
73
|
+
Kashi::SecretProviders.const_get(name.split('_').map(&:capitalize).join('')).new
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/kashi/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kashi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- wata
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: statuscake
|
@@ -133,7 +133,9 @@ files:
|
|
133
133
|
- lib/kashi/dsl/contact_group.rb
|
134
134
|
- lib/kashi/dsl/test.rb
|
135
135
|
- lib/kashi/ext/string-ext.rb
|
136
|
+
- lib/kashi/filterable.rb
|
136
137
|
- lib/kashi/output_test.erb
|
138
|
+
- lib/kashi/secret_expander.rb
|
137
139
|
- lib/kashi/utils.rb
|
138
140
|
- lib/kashi/version.rb
|
139
141
|
homepage: https://github.com/wata-gh/kashi
|
@@ -151,12 +153,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
151
153
|
version: '0'
|
152
154
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
155
|
requirements:
|
154
|
-
- - "
|
156
|
+
- - ">="
|
155
157
|
- !ruby/object:Gem::Version
|
156
|
-
version:
|
158
|
+
version: '0'
|
157
159
|
requirements: []
|
158
160
|
rubyforge_project:
|
159
|
-
rubygems_version: 2.6.
|
161
|
+
rubygems_version: 2.6.13
|
160
162
|
signing_key:
|
161
163
|
specification_version: 4
|
162
164
|
summary: Codenize StatusCake
|