kashi 0.1.0.beta1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|