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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '055328ffe3f5ea256bb7b5a93ff93b955a87f502'
4
- data.tar.gz: 772ae8d3b42689c100d474a375676790f3366377
3
+ metadata.gz: d7331c135793bad57b313139dcfc55669b67e7bf
4
+ data.tar.gz: f561bf7f18a29b38e489e042d453c68eddc9eeac
5
5
  SHA512:
6
- metadata.gz: af45c16beb5e36f27cfde874292f3f1c659cbc3639376f4aad54b15609f1035c937c17a09a3ea4cd629a8df35c00100b8a23d7e930a64f0e4f182a37268d8acd
7
- data.tar.gz: '0928ab0904b4f029cae919d0981216fbad95041e06b952923dd34ecddd20031e80d286ac6d42a936add1075b50cd4819513af5deb807bc6d6d1458d68ed97a94'
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
- check_rate 300
78
- timeout 40
79
- website_host ""
80
- node_locations ["freeserver2"]
83
+
84
+ # Scans
85
+ enable_ssl_warning 1
86
+
87
+ # HTTP Communication Options
81
88
  find_string ""
82
89
  do_not_find 0
83
- logo_image ""
84
-
90
+ follow_redirect 1
85
91
  custom_header(
86
92
  {"Host"=>"example.com"}
87
93
  )
88
- confirmation "2"
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
- basic_user nil
91
- basic_pass nil
96
+ logo_image ""
92
97
 
93
- use_jar nil
98
+ # Test Locations
99
+ node_locations ["freeserver11"]
94
100
 
95
- dns_ip ""
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
- 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"]
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
- dsl_tests_by_name = dsl_tests.group_by(&:website_name)
56
- dsl_tests_by_id = dsl_tests.group_by(&:test_id)
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|
@@ -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
- tests tests_details tests_update
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
@@ -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
- Kashi.logger.info("<diff>\n#{Kashi::Utils.diff(sc_hash, dsl_hash, color: @options[:color])}")
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
@@ -1,3 +1,3 @@
1
1
  module Kashi
2
- VERSION = '0.1.0.beta1'
2
+ VERSION = '0.1.0'
3
3
  end
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.beta1
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-07-06 00:00:00.000000000 Z
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: 1.3.1
158
+ version: '0'
157
159
  requirements: []
158
160
  rubyforge_project:
159
- rubygems_version: 2.6.11
161
+ rubygems_version: 2.6.13
160
162
  signing_key:
161
163
  specification_version: 4
162
164
  summary: Codenize StatusCake