chef-telemetry 0.1.8 → 1.0.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
  SHA256:
3
- metadata.gz: 7319019f20b68bb77f02c28dcdaa9dced791613f5af25c0ad43b095f55764756
4
- data.tar.gz: 2fb617610995a63967cd6f00c500764aa45282518e77046d2c8fc3bd83cd8e39
3
+ metadata.gz: faf29c758b1dbcddd569962312d55a7f9b7648ac2fed2896a962360f62d50b93
4
+ data.tar.gz: '079575327ecc06c86e9fb305cd4e0b6339ea443ad53800006f74baa710d9f266'
5
5
  SHA512:
6
- metadata.gz: 8914e2941c35f42086f89a0bb5da066c8c069aaee72466bfc74a55d96c0972cba8c5c275aadbef3fba54eb5eb86527655fd43c6f80e007818122cef06b9b5038
7
- data.tar.gz: 06163b5ddb874c882a7c51046f4f5e34c9412e857e767fe79f2258da8ff27d93666391af58077eef2eae12b2f308cba73953fd5de56de34ea9b942c4b7b0c4f8
6
+ metadata.gz: 35a60bfa480f9085eac39bd3f1699ab2926f1c270e947439c13bfbc585e97849b5cb155bf8eaadef41496fc0a62c13867dc25b3380ece12d1460e84fee8794aa
7
+ data.tar.gz: 4bd4017b173ba7a50f5888550c16e1b0616c0a2b6176ba719513bad27ece43ce32dca9208ad7a891e519e3d957e64c26ce8ef56e20ca2eace83383c743b81592
@@ -0,0 +1,162 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2018 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require "chef/telemetry/version"
19
+ require "benchmark"
20
+ require "forwardable"
21
+ require "singleton"
22
+ require "json"
23
+ require "digest/sha1"
24
+ require "securerandom"
25
+ require "yaml"
26
+
27
+ module Chef
28
+ # This definites the Telemeter interface. Implementation thoughts for
29
+ # when we unstub it:
30
+ # - let's track the call sequence; most of our calls will be nested inside
31
+ # a main 'timed_capture', and it would be good to see ordering within nested calls.
32
+ class Telemeter
33
+ include Singleton
34
+ DEFAULT_INSTALLATION_GUID = "00000000-0000-0000-0000-000000000000".freeze
35
+
36
+ class << self
37
+ extend Forwardable
38
+ def_delegators :instance, :setup, :timed_capture, :capture, :commit, :timed_run_capture
39
+ def_delegators :instance, :pending_event_count, :last_event, :enabled?
40
+ def_delegators :instance, :make_event_payload, :config
41
+ end
42
+
43
+ attr_reader :events_to_send, :run_timestamp, :config
44
+
45
+ def setup(config)
46
+ # TODO validate required & correct keys
47
+ # :payload_dir #required
48
+ # :session_file # required
49
+ # :installation_identifier_file # required
50
+ # :enabled # false, not required
51
+ # :dev_mode # false, not required
52
+ config[:dev_mode] ||= false
53
+ config[:enabled] ||= false
54
+ require "chef_core/telemeter/sender"
55
+ @config = config
56
+ Sender.start_upload_thread(config)
57
+ end
58
+
59
+ def enabled?
60
+ require "chef/telemetry/decision"
61
+ config[:enabled] && !Telemetry::Decision.env_opt_out?
62
+ end
63
+
64
+ def initialize
65
+ @events_to_send = []
66
+ @run_timestamp = Time.now.utc.strftime("%FT%TZ")
67
+ end
68
+
69
+ def timed_run_capture(arguments, &block)
70
+ timed_capture(:run, arguments: arguments, &block)
71
+ end
72
+
73
+ def timed_capture(name, data = {}, options = {})
74
+ time = Benchmark.measure { yield }
75
+ data[:duration] = time.real
76
+ capture(name, data, options)
77
+ end
78
+
79
+ def capture(name, data = {}, options = {})
80
+ # Adding it to the head of the list will ensure that the
81
+ # sequence of events is preserved when we send the final payload
82
+ payload = make_event_payload(name, data, options)
83
+ @events_to_send.unshift payload
84
+ end
85
+
86
+ def commit
87
+ if enabled?
88
+ session = convert_events_to_session
89
+ write_session(session)
90
+ end
91
+ @events_to_send = []
92
+ end
93
+
94
+ def make_event_payload(name, data, options = {})
95
+ payload = {
96
+ event: name,
97
+ properties: {
98
+ installation_id: installation_id,
99
+ run_timestamp: run_timestamp,
100
+ host_platform: host_platform,
101
+ },
102
+ }
103
+ if options[:flatten]
104
+ payload[:properties].merge! data
105
+ else
106
+ payload[:properties][:event_data] = data
107
+ end
108
+ payload
109
+ end
110
+
111
+ def installation_id
112
+ @installation_id ||=
113
+ begin
114
+ File.read(config[:installation_identifier_file]).chomp
115
+ rescue
116
+ Telemeter::Log.info "could not read #{config[:installation_identifier_file]} - using default id"
117
+ DEFAULT_INSTALLATION_GUID
118
+ end
119
+ end
120
+
121
+ # For testing.
122
+ def pending_event_count
123
+ @events_to_send.length
124
+ end
125
+
126
+ def last_event
127
+ @events_to_send.last
128
+ end
129
+
130
+ private
131
+
132
+ def host_platform
133
+ @host_platform ||= case RUBY_PLATFORM
134
+ when /mswin|mingw|windows/
135
+ "windows"
136
+ else
137
+ RUBY_PLATFORM.split("-")[1]
138
+ end
139
+ end
140
+
141
+ def convert_events_to_session
142
+ YAML.dump("version" => Telemetry::VERSION,
143
+ "entries" => @events_to_send)
144
+ end
145
+
146
+ def write_session(session)
147
+ File.write(next_filename, convert_events_to_session)
148
+ end
149
+
150
+ def next_filename
151
+ id = 0
152
+ filename = ""
153
+ loop do
154
+ id += 1
155
+ filename = File.join(config[:payload_dir], "telemetry-payload-#{id}.yml")
156
+ break unless File.exist?(filename)
157
+ end
158
+ filename
159
+ end
160
+
161
+ end
162
+ end # Chef
@@ -0,0 +1,125 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2018 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require "chef/telemetry"
19
+ require "chef/telemeter"
20
+ require "logger"
21
+
22
+ module Chef
23
+ class Telemeter
24
+ logger = ::Logger.new(STDERR) # TODO: maybe switch to file, maybe switch to mixlib
25
+ logger.level = Logger::ERROR
26
+ Log = logger # rubocop:disable Naming/ConstantName
27
+
28
+ class Sender
29
+ attr_reader :session_files, :config
30
+
31
+ def self.start_upload_thread(config)
32
+ # Find the files before we spawn the thread - otherwise
33
+ # we may accidentally pick up the current run's session file if it
34
+ # finishes before the thread scans for new files
35
+ session_files = Sender.find_session_files(config)
36
+ sender = Sender.new(session_files, config)
37
+ Thread.new { sender.run }
38
+ end
39
+
40
+ def self.find_session_files(config)
41
+ Telemeter::Log.info("Looking for telemetry data to submit")
42
+ session_search = File.join(config[:payload_dir], "telemetry-payload-*.yml")
43
+ session_files = Dir.glob(session_search)
44
+ Telemeter::Log.info("Found #{session_files.length} sessions to submit")
45
+ session_files
46
+ end
47
+
48
+ def initialize(session_files, config)
49
+ @session_files = session_files
50
+ @config = config
51
+ end
52
+
53
+ def run
54
+ if Telemeter.enabled?
55
+ Telemeter::Log.info("Telemetry enabled, beginning upload of previous session(s)")
56
+ # dev mode telemetry gets sent to a different location
57
+
58
+ if config[:dev_mode]
59
+ ENV["CHEF_TELEMETRY_ENDPOINT"] ||= "https://telemetry-acceptance.chef.io"
60
+ end
61
+ session_files.each { |path| process_session(path) }
62
+ else
63
+ # If telemetry is not enabled, just clean up and return. Even though
64
+ # the telemetry gem will not send if disabled, log output saying that we're submitting
65
+ # it when it has been disabled can be alarming.
66
+ Telemeter::Log.info("Telemetry disabled, clearing any existing session captures without sending them.")
67
+ session_files.each { |path| FileUtils.rm_rf(path) }
68
+ end
69
+ FileUtils.rm_rf(config[:session_file])
70
+ Telemeter::Log.info("Terminating, nothing more to do.")
71
+ rescue => e
72
+ Telemeter::Log.fatal "Sender thread aborted: '#{e}' failed at #{e.backtrace[0]}"
73
+ end
74
+
75
+ def process_session(path)
76
+ Telemeter::Log.info("Processing telemetry entries from #{path}")
77
+ content = load_and_clear_session(path)
78
+ submit_session(content)
79
+ end
80
+
81
+ def submit_session(content)
82
+ # Each file contains the actions taken within a single run of the chef tool.
83
+ # Each run is one session, so we'll first remove remove the session file
84
+ # to force creating a new one.
85
+ FileUtils.rm_rf(config[:session_file])
86
+ # We'll use the version captured in the sesion file
87
+ entries = content["entries"]
88
+ total = entries.length
89
+ product_info = config[:product] || {}
90
+ telemetry = Telemetry.new(product: product_info[:name] || "chef-workstation",
91
+ origin: product_info[:origin] || "command-line",
92
+ product_version: product_info[:version] || content["version"],
93
+ install_context: product_info[:install_context] || "omnibus")
94
+ total = entries.length
95
+ entries.each_with_index do |entry, x|
96
+ submit_entry(telemetry, entry, x + 1, total)
97
+ end
98
+ end
99
+
100
+ def submit_entry(telemetry, entry, sequence, total)
101
+ Telemeter::Log.info("Submitting telemetry entry #{sequence}/#{total}: #{entry} ")
102
+ telemetry.deliver(entry)
103
+ Telemeter::Log.info("Entry #{sequence}/#{total} submitted.")
104
+ rescue => e
105
+ # No error handling in telemetry lib, so at least track the failrue
106
+ Telemeter::Log.error("Failed to send entry #{sequence}/#{total}: #{e}")
107
+ Telemeter::Log.error("Backtrace: #{e.backtrace} ")
108
+ end
109
+
110
+ private
111
+
112
+ def load_and_clear_session(path)
113
+ content = File.read(path)
114
+ # We'll remove it now instead of after we parse or submit it -
115
+ # if we fail to deliver, we don't want to be stuck resubmitting it if the problem
116
+ # was due to payload. This is a trade-off - if we get a transient error, the
117
+ # payload will be lost.
118
+ # TODO: Improve error handling so we can intelligently decide whether to
119
+ # retry a failed load or failed submit.
120
+ FileUtils.rm_rf(path)
121
+ YAML.load(content)
122
+ end
123
+ end
124
+ end
125
+ end # Chef
@@ -0,0 +1,45 @@
1
+ require "chef/telemetry/client"
2
+ require "chef/telemetry/decision"
3
+ require "chef/telemetry/event"
4
+ require "chef/telemetry/session"
5
+ require "chef/telemetry/version"
6
+
7
+ module Chef
8
+ class Telemetry
9
+ attr_accessor :product, :origin, :product_version, :install_context
10
+ def initialize(product: nil, origin: "command-line",
11
+ product_version: "0.0.0",
12
+ install_context: "omnibus")
13
+ # Reference: https://github.com/chef/es-telemetry-pipeline/blob/0730c1e2605624a50d34bab6d036b73c31e0ab0e/schema/event.schema.json#L77
14
+ @product = product
15
+ @origin = origin
16
+ @product_version = product_version
17
+ @install_context = install_context # Valid: habitat, omnibus
18
+ end
19
+
20
+ def deliver(data = {})
21
+ unless opt_out?
22
+ payload = event.prepare(data)
23
+ client.await.fire(payload)
24
+ end
25
+ end
26
+
27
+ def event
28
+ @event ||= Event.new(product, session, origin,
29
+ install_context, product_version)
30
+ end
31
+
32
+ def session
33
+ @session ||= Session.new
34
+ end
35
+
36
+ def opt_out?
37
+ @opt_out ||= Decision.opt_out?
38
+ end
39
+
40
+ def client
41
+ endpoint = ENV.fetch("CHEF_TELEMETRY_ENDPOINT", Client::TELEMETRY_ENDPOINT)
42
+ @client ||= Client.new(endpoint)
43
+ end
44
+ end
45
+ end # Chef
@@ -0,0 +1,26 @@
1
+ require "http"
2
+ require "concurrent"
3
+
4
+ module Chef
5
+ class Telemetry
6
+ class Client
7
+ include Concurrent::Async
8
+
9
+ TELEMETRY_ENDPOINT = "https://telemetry.chef.io".freeze
10
+
11
+ attr_reader :http
12
+ def initialize(endpoint = TELEMETRY_ENDPOINT)
13
+ super()
14
+ @http = HTTP.persistent(endpoint)
15
+ end
16
+
17
+ def fire(event)
18
+ http.post("/events", json: event).flush
19
+ end
20
+ end
21
+
22
+ class OptOutClient
23
+ def fire(_); end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,67 @@
1
+ require "chef-config/path_helper"
2
+ require "chef-config/windows"
3
+
4
+ # Decision allows us to inspect whether the user has made a decision to opt in or opt out of telemetry.
5
+ module Chef
6
+ class Telemetry
7
+ module Decision
8
+ OPT_OUT_FILE = "telemetry_opt_out".freeze
9
+ OPT_IN_FILE = "telemetry_opt_in".freeze
10
+
11
+ class << self
12
+ def opt_out?
13
+ # We check that the user has made a decision so that we can have a default setting for robots
14
+ user_opted_out? || env_opt_out? || local_opt_out? || !made?
15
+ end
16
+
17
+ # Check whether the user has made an explicit decision on their participation.
18
+ def made?
19
+ user_opted_in? || user_opted_out?
20
+ end
21
+
22
+ def user_opted_out?
23
+ File.exist?(File.join(home, OPT_OUT_FILE))
24
+ end
25
+
26
+ def user_opted_in?
27
+ File.exist?(File.join(home, OPT_IN_FILE))
28
+ end
29
+
30
+ def env_opt_out?
31
+ ENV.key?("CHEF_TELEMETRY_OPT_OUT")
32
+ end
33
+
34
+ def local_opt_out?
35
+ found = false
36
+ full_path = working_directory.split(File::SEPARATOR)
37
+ (full_path.length - 1).downto(0) do |i|
38
+ candidate = File.join(full_path[0..i], ".chef", OPT_OUT_FILE)
39
+ if File.exist?(candidate)
40
+ # TODO: push up logging
41
+ # Log.info "Found opt out at: #{candidate}"
42
+ found = true
43
+ break
44
+ end
45
+ end
46
+ found
47
+ end
48
+
49
+ private
50
+
51
+ def working_directory
52
+ a = if ChefConfig.windows?
53
+ ENV["CD"]
54
+ else
55
+ ENV["PWD"]
56
+ end || Dir.pwd
57
+
58
+ a
59
+ end
60
+
61
+ def home
62
+ ChefConfig::PathHelper.home(".chef")
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end # Chef
@@ -0,0 +1,44 @@
1
+ module Chef
2
+ class Telemetry
3
+ class Event
4
+
5
+ SKELETON = {
6
+ instance_id: "00000000-0000-0000-0000-000000000000",
7
+ message_version: 1.0,
8
+ payload_version: 1.0,
9
+ license_id: "00000000-0000-0000-0000-000000000000",
10
+ type: "track",
11
+ }.freeze
12
+
13
+ attr_reader :session, :product, :origin,
14
+ :product_version, :install_context
15
+ def initialize(product, session, origin = "command-line",
16
+ install_context = "omnibus", product_version = "0.0.0")
17
+ @product = product
18
+ @session = session
19
+ @origin = origin
20
+ @product_version = product_version
21
+ @install_context = install_context
22
+ end
23
+
24
+ def prepare(event)
25
+ time = timestamp
26
+ event[:properties][:timestamp] = time
27
+ body = SKELETON.dup
28
+ body.tap do |b|
29
+ b[:session_id] = session.id
30
+ b[:origin] = origin
31
+ b[:product] = product
32
+ b[:product_version] = product_version
33
+ b[:install_context] = install_context
34
+ b[:timestamp] = time
35
+ b[:payload] = event
36
+ end
37
+ end
38
+
39
+ def timestamp
40
+ Time.now.utc.strftime("%FT%TZ")
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,39 @@
1
+ require "securerandom"
2
+ require "chef-config/path_helper"
3
+
4
+ module Chef
5
+ class Telemetry
6
+ class Session
7
+ def initialize
8
+ @id = if live_session?
9
+ File.read(session_file).chomp
10
+ else
11
+ new_session
12
+ end
13
+ end
14
+
15
+ def id
16
+ FileUtils.touch(session_file)
17
+ @id
18
+ end
19
+
20
+ private
21
+
22
+ def live_session?
23
+ expiry = Time.now - 600
24
+ File.file?(session_file) && File.stat(session_file).mtime > expiry
25
+ end
26
+
27
+ def session_file
28
+ File.join(ChefConfig::PathHelper.home(".chef"), "TELEMETRY_SESSION_ID").freeze
29
+ end
30
+
31
+ def new_session
32
+ id = SecureRandom.uuid
33
+ FileUtils.mkdir_p(File.dirname(session_file))
34
+ File.open(session_file, "w") { |f| f.write(id) }
35
+ id
36
+ end
37
+ end
38
+ end
39
+ end # Chef
@@ -0,0 +1,5 @@
1
+ module Chef
2
+ class Telemetry
3
+ VERSION = "1.0.0".freeze
4
+ end
5
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-telemetry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef Software, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-16 00:00:00.000000000 Z
11
+ date: 2019-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -87,12 +87,14 @@ extensions: []
87
87
  extra_rdoc_files: []
88
88
  files:
89
89
  - LICENSE
90
- - lib/telemetry.rb
91
- - lib/telemetry/client.rb
92
- - lib/telemetry/decision.rb
93
- - lib/telemetry/event.rb
94
- - lib/telemetry/session.rb
95
- - lib/telemetry/version.rb
90
+ - lib/chef/telemeter.rb
91
+ - lib/chef/telemeter/sender.rb
92
+ - lib/chef/telemetry.rb
93
+ - lib/chef/telemetry/client.rb
94
+ - lib/chef/telemetry/decision.rb
95
+ - lib/chef/telemetry/event.rb
96
+ - lib/chef/telemetry/session.rb
97
+ - lib/chef/telemetry/version.rb
96
98
  homepage: https://github.com/chef/chef-telemetry
97
99
  licenses:
98
100
  - Apache-2.0
@@ -112,8 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
114
  - !ruby/object:Gem::Version
113
115
  version: '0'
114
116
  requirements: []
115
- rubyforge_project:
116
- rubygems_version: 2.7.6
117
+ rubygems_version: 3.0.3
117
118
  signing_key:
118
119
  specification_version: 4
119
120
  summary: Send user actions to the Chef telemetry system. See Chef RFC-051 for further
@@ -1,43 +0,0 @@
1
- require "telemetry/client"
2
- require "telemetry/decision"
3
- require "telemetry/event"
4
- require "telemetry/session"
5
- require "telemetry/version"
6
-
7
- class Telemetry
8
- attr_accessor :product, :origin, :product_version, :install_context
9
- def initialize(product: nil, origin: "command-line",
10
- product_version: "0.0.0",
11
- install_context: "omnibus")
12
- # Reference: https://github.com/chef/es-telemetry-pipeline/blob/0730c1e2605624a50d34bab6d036b73c31e0ab0e/schema/event.schema.json#L77
13
- @product = product
14
- @origin = origin
15
- @product_version = product_version
16
- @install_context = install_context # Valid: habitat, omnibus
17
- end
18
-
19
- def deliver(data = {})
20
- unless opt_out?
21
- payload = event.prepare(data)
22
- client.await.fire(payload)
23
- end
24
- end
25
-
26
- def event
27
- @event ||= Event.new(product, session, origin,
28
- install_context, product_version)
29
- end
30
-
31
- def session
32
- @session ||= Session.new
33
- end
34
-
35
- def opt_out?
36
- @opt_out ||= Decision.opt_out?
37
- end
38
-
39
- def client
40
- endpoint = ENV.fetch("CHEF_TELEMETRY_ENDPOINT", Client::TELEMETRY_ENDPOINT)
41
- @client ||= Client.new(endpoint)
42
- end
43
- end
@@ -1,24 +0,0 @@
1
- require "http"
2
- require "concurrent"
3
-
4
- class Telemetry
5
- class Client
6
- include Concurrent::Async
7
-
8
- TELEMETRY_ENDPOINT = "https://telemetry.chef.io".freeze
9
-
10
- attr_reader :http
11
- def initialize(endpoint = TELEMETRY_ENDPOINT)
12
- super()
13
- @http = HTTP.persistent(endpoint)
14
- end
15
-
16
- def fire(event)
17
- http.post("/events", json: event).flush
18
- end
19
- end
20
-
21
- class OptOutClient
22
- def fire(_); end
23
- end
24
- end
@@ -1,64 +0,0 @@
1
- require "chef-config/path_helper"
2
- require "chef-config/windows"
3
-
4
- # Decision allows us to inspect whether the user has made a decision to opt in or opt out of telemetry.
5
- class Telemetry
6
- module Decision
7
- OPT_OUT_FILE = "telemetry_opt_out".freeze
8
- OPT_IN_FILE = "telemetry_opt_in".freeze
9
-
10
- class << self
11
- def opt_out?
12
- # We check that the user has made a decision so that we can have a default setting for robots
13
- user_opted_out? || env_opt_out? || local_opt_out? || !made?
14
- end
15
-
16
- # Check whether the user has made an explicit decision on their participation.
17
- def made?
18
- user_opted_in? || user_opted_out?
19
- end
20
-
21
- def user_opted_out?
22
- File.exist?(File.join(home, OPT_OUT_FILE))
23
- end
24
-
25
- def user_opted_in?
26
- File.exist?(File.join(home, OPT_IN_FILE))
27
- end
28
-
29
- def env_opt_out?
30
- ENV.key?("CHEF_TELEMETRY_OPT_OUT")
31
- end
32
-
33
- def local_opt_out?
34
- found = false
35
- full_path = working_directory.split(File::SEPARATOR)
36
- (full_path.length - 1).downto(0) do |i|
37
- candidate = File.join(full_path[0..i], ".chef", OPT_OUT_FILE)
38
- if File.exist?(candidate)
39
- puts "Found opt out at: #{candidate}"
40
- found = true
41
- break
42
- end
43
- end
44
- found
45
- end
46
-
47
- private
48
-
49
- def working_directory
50
- a = if ChefConfig.windows?
51
- ENV["CD"]
52
- else
53
- ENV["PWD"]
54
- end || Dir.pwd
55
-
56
- a
57
- end
58
-
59
- def home
60
- ChefConfig::PathHelper.home(".chef")
61
- end
62
- end
63
- end
64
- end
@@ -1,42 +0,0 @@
1
- class Telemetry
2
- class Event
3
-
4
- SKELETON = {
5
- instance_id: "00000000-0000-0000-0000-000000000000",
6
- message_version: 1.0,
7
- payload_version: 1.0,
8
- license_id: "00000000-0000-0000-0000-000000000000",
9
- type: "track",
10
- }.freeze
11
-
12
- attr_reader :session, :product, :origin,
13
- :product_version, :install_context
14
- def initialize(product, session, origin = "command-line",
15
- install_context = "omnibus", product_version = "0.0.0")
16
- @product = product
17
- @session = session
18
- @origin = origin
19
- @product_version = product_version
20
- @install_context = install_context
21
- end
22
-
23
- def prepare(event)
24
- time = timestamp
25
- event[:properties][:timestamp] = time
26
- body = SKELETON.dup
27
- body.tap do |b|
28
- b[:session_id] = session.id
29
- b[:origin] = origin
30
- b[:product] = product
31
- b[:product_version] = product_version
32
- b[:install_context] = install_context
33
- b[:timestamp] = time
34
- b[:payload] = event
35
- end
36
- end
37
-
38
- def timestamp
39
- Time.now.utc.strftime("%FT%TZ")
40
- end
41
- end
42
- end
@@ -1,37 +0,0 @@
1
- require "securerandom"
2
- require "chef-config/path_helper"
3
-
4
- class Telemetry
5
- class Session
6
- def initialize
7
- @id = if live_session?
8
- File.read(session_file).chomp
9
- else
10
- new_session
11
- end
12
- end
13
-
14
- def id
15
- FileUtils.touch(session_file)
16
- @id
17
- end
18
-
19
- private
20
-
21
- def live_session?
22
- expiry = Time.now - 600
23
- File.file?(session_file) && File.stat(session_file).mtime > expiry
24
- end
25
-
26
- def session_file
27
- File.join(ChefConfig::PathHelper.home(".chef"), "TELEMETRY_SESSION_ID").freeze
28
- end
29
-
30
- def new_session
31
- id = SecureRandom.uuid
32
- FileUtils.mkdir_p(File.dirname(session_file))
33
- File.open(session_file, "w") { |f| f.write(id) }
34
- id
35
- end
36
- end
37
- end
@@ -1,3 +0,0 @@
1
- class Telemetry
2
- VERSION = "0.1.8".freeze
3
- end