upman-daemon 0.0.8.4 → 0.0.8.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5c7ac163d0dd1ba6132fb4a7c3c77a9e5131b20bd158d473de4f576ad858583
4
- data.tar.gz: 88631e841be85e59c2f8a00e13028771d4eaf03ff4142e4d199852275390d2c8
3
+ metadata.gz: b51d88026c608d0d4eb752780f0d44c611789e8cbf177fc818800a1447121249
4
+ data.tar.gz: b9d3627a649d7e69f4b012ebd0a3328d63957e59c115396e2c4d06832d260645
5
5
  SHA512:
6
- metadata.gz: a2768d6f096fac1b3a43cd5fe159afa2a1c906a0b08ae61ebc6855d6475433f2d9d3c98815ceafe6ab32413ef75af64bf66b6f0800034596b918024aa05ac3ac
7
- data.tar.gz: 9a14dc77f12af966feb76523faf26ef2fdd114d0fa8daafcce3bc0c0055f7c7974152bb542c0be96d1f302406302c72c93887f231f7ac5b5688f1f6a5382eb4a
6
+ metadata.gz: eeb4c315bbc741bd15dbe860f4546255f774b5263a93fcc864e2d04cdbb330346b96bee953dbbf4fdee7bea18821a74abb27746eff68a7bac3a2e55197affef3
7
+ data.tar.gz: 3ae68734a94fb756a63a0cc2cf6576a8593401e63d67b3ef0382798e7ee25b017b7bd67b897ba9bc871060edb462bc4264f181f0ada64c24bdfbc0d1712bc551
data/lib/upman.rb CHANGED
@@ -15,10 +15,15 @@ require_relative 'upman/core/config'
15
15
  require_relative 'upman/core/extension_base'
16
16
  require_relative 'upman/core/worker'
17
17
 
18
+ require_relative 'upman/services/node'
19
+ require_relative 'upman/services/install_history'
20
+ require_relative 'upman/services/installed_packages'
18
21
 
19
22
  require_relative 'upman/server/socket'
20
23
  require_relative 'upman/server/base_servlet'
21
24
 
25
+ require_relative 'upman/worker/base_worker'
26
+
22
27
  module Upman
23
28
  def self.run!(options)
24
29
  config_file = nil
@@ -1,50 +1,17 @@
1
- module Upman
2
- module Core
3
- class Register
4
- include ::Upman::Utils::Helper
5
- using SymbolizeHelper
6
- require 'securerandom'
7
-
8
- require 'facter'
9
- attr_accessor :hostdata_file
10
-
11
- def initialize
12
- @hostdata_file = 'hostdata.yml'
13
- end
14
-
15
- def perform
16
- data = generate_host_data
17
- info "Register Daemon running on #{data[:hostname]} with foreman_upman"
18
-
19
- api = ::Upman::Utils::Api.new
20
- api.post("upman/node/register", data.to_json)
21
- end
22
-
23
- def generate_host_data
24
- unless File.exist? @hostdata_file
25
- data = {
26
- :hostname => Socket.gethostbyname(Socket.gethostname).first,
27
- :uuid => SecureRandom.uuid,
28
- }
29
- File.write(@hostdata_file, data.to_yaml)
30
- end
31
- update_node_data
32
- end
33
-
34
- def update_node_data
35
- if File.exist? @hostdata_file
36
- data = YAML::load_file(@hostdata_file).deep_symbolize_keys
37
- data.merge!({
38
- :operatingsystem => Facter['operatingsystem'].value,
39
- :rubyversion => Facter['rubyversion'].value,
40
- :operatingsystemrelease => Facter['operatingsystemrelease'].value,
41
- :last_sync => DateTime.now
42
- })
43
- File.write(@hostdata_file, data.to_yaml)
44
- end
45
- data
46
- end
47
-
48
- end
49
- end
1
+ module Upman
2
+ module Core
3
+ class Register
4
+ include ::Upman::Utils::Helper
5
+
6
+ def perform
7
+ node_service = Upman::Service::Node.new
8
+ data = node_service.generate_node_data
9
+ info "Register Daemon running on #{data[:hostname]} with foreman_upman"
10
+
11
+ api = ::Upman::Utils::Api.new
12
+ api.post("upman/node/register", data.to_json)
13
+ end
14
+
15
+ end
16
+ end
50
17
  end
@@ -3,33 +3,50 @@ module Upman
3
3
  class Worker
4
4
 
5
5
  include Upman::Utils::Helper
6
+ include Upman::Utils::Dynload
7
+
8
+ attr_accessor :workers, :worker_threads
6
9
 
7
10
  def initialize
8
11
  @stop_signal = true
12
+ @config = ::Upman::Core::Config.daemon
13
+ @workers = []
14
+ @worker_threads = []
15
+
16
+ register_worker
9
17
  end
10
18
 
11
19
  def run!
12
- _banner
13
- while @stop_signal
14
- self.perform
15
- sleep(::Upman::Core::Config.daemon[:interval])
16
- end
20
+ show_banner
17
21
 
22
+ @workers.each do |worker|
23
+ @worker_threads << Thread.new do
24
+ worker.run!
25
+ end
26
+ end
27
+ @worker_threads.each { |t| t.join }
18
28
  end
19
29
 
20
30
  def shutdown
21
- info "Stopping working thread"
31
+ info "Stopping Worker Threads"
22
32
  @stop_signal = false
23
33
  end
24
34
 
25
35
 
26
- def perform
27
- info "Doing some work"
36
+ def register_worker
37
+ @config[:workers].each do |worker|
38
+ require_relative "../../upman/worker/#{worker}"
39
+ ext_obj = dynload("Upman::Worker::#{worker.split('_').map(&:capitalize).join('')}")
40
+ info "Register Worker Thread Upman::Worker::#{worker.split('_').map(&:capitalize).join('')}"
41
+ ext_class = ext_obj .new
42
+ @workers.append ext_class.register
43
+ end
28
44
  end
29
45
 
46
+
30
47
  private
31
48
 
32
- def _banner
49
+ def show_banner
33
50
  info "Running UpMan #{::Upman::Version::VERSION}"
34
51
  end
35
52
 
@@ -23,6 +23,11 @@ module Upman
23
23
 
24
24
  super(request, response)
25
25
 
26
+ unless is_authenticated(request)
27
+ response = not_authorized(response, "Request declined")
28
+ return response
29
+ end
30
+
26
31
  unless (@param_since = get_param('since', 'date', false))
27
32
  return nil
28
33
  end
@@ -33,56 +38,10 @@ module Upman
33
38
  end
34
39
 
35
40
  def perform_action
36
- result = []
37
- i = 0
38
- hist_lines = fetch_history.split("\n")
39
- hist_lines.each do |history|
40
- fill_up(result, i, hist_lines, history) if i.even?
41
- i += 1
42
- end
43
- result.to_json
44
- end
45
-
46
- private
47
-
48
- def fetch_history
49
- command = '(zcat $(ls -tr /var/log/apt/history.log*.gz); '\
50
- 'cat /var/log/apt/history.log) ' \
51
- '2>/dev/null | egrep \'^(Start-Date:|Commandline:)\' | '\
52
- 'grep -v aptdaemon'
53
- `#{command}`
41
+ install_history_service = ::Upman::Service::InstallHistory.new
42
+ install_history_service.get(@param_since).to_json
54
43
  end
55
44
 
56
- def fill_up(result, line_index, hist_lines, history)
57
- line = hist_lines[line_index + 1].sub('Commandline: ', '')
58
- command = parse_command(line)
59
- return nil if command.empty?
60
-
61
- command[:start_date] = DateTime.parse(history.sub('Start-Date: ', ''))
62
-
63
- if @param_since.instance_of?(Date)
64
- if command[:start_date] >= @param_since
65
- result.append command
66
- end
67
- else
68
- result.append command
69
- end
70
- end
71
-
72
- def parse_command(command_line)
73
- package = {}
74
- regexp = /(apt(-get)?)(( [\-\w]*)*) (install|upgrade|purge)(.*)?/
75
- if (matches = command_line.match(regexp))
76
- package[:action] = matches[5].strip
77
-
78
- package[:options] = []
79
- matches[3].split(' ').each { |name| package[:options].append name }
80
-
81
- package[:packages] = []
82
- matches[6].split(' ').each { |name| package[:packages].append name }
83
- end
84
- package
85
- end
86
45
  end
87
46
  end
88
47
  end
@@ -11,14 +11,17 @@ module Upman
11
11
 
12
12
  attr_accessor :requested
13
13
 
14
- include ::Upman::Utils::Parser
15
-
16
14
  # rubocop:disable Naming/MethodName
17
15
  def do_GET(request, response)
18
16
  # rubocop:enable Naming/MethodName
19
17
 
20
18
  super(request, response)
21
19
 
20
+ unless is_authenticated(request)
21
+ response = not_authorized(response, "Request declined")
22
+ return response
23
+ end
24
+
22
25
  @requested = get_param('requested', 'int')
23
26
 
24
27
  if (body = perform_action)
@@ -27,20 +30,8 @@ module Upman
27
30
  end
28
31
 
29
32
  def perform_action
30
- result = []
31
- extended_states = File.open('/var/lib/apt/extended_states', 'rb', &:read)
32
- extended_states.split("\n\n").each do |chunk|
33
- installed_packages = _get_hashed_values(chunk)
34
- unless @requested.empty?
35
- if installed_packages['auto_installed'] == @requested
36
- result.append installed_packages
37
- end
38
- else
39
- result.append installed_packages
40
- end
41
-
42
- end
43
- result.to_json
33
+ installed_package_service = Upman::Service::InstalledPackages.new
34
+ installed_package_service.get(@requested).to_json
44
35
  end
45
36
 
46
37
  end
@@ -8,17 +8,33 @@ module Upman
8
8
  return Servlet
9
9
  end
10
10
 
11
- class Servlet < WEBrick::HTTPServlet::AbstractServlet
12
- def do_GET request, response
13
- response.status = 200
14
- response['Content-Type'] = 'application/json'
15
- response.body = self.perform_action
16
- end
11
+ # Servlet action for WEBrick
12
+ class Servlet < ::Upman::Server::BaseServlet
13
+
14
+ attr_accessor :payload
15
+
16
+ # rubocop:disable Naming/MethodName
17
+ def do_GET(request, response)
18
+ # rubocop:enable Naming/MethodName
19
+
20
+ super(request, response)
17
21
 
22
+ unless is_authenticated(request)
23
+ response = not_authorized(response, "Request declined")
24
+ return response
25
+ end
26
+
27
+ @payload = get_param('payload', 'json', false)
28
+
29
+ if (body = perform_action)
30
+ response = ok(response, body)
31
+ end
32
+ end
18
33
 
19
34
  def perform_action
20
- "installPackage"
35
+ "{\"autentication\": \"failed - no valid certifacte was given\"}"
21
36
  end
37
+
22
38
  end
23
39
 
24
40
  end
@@ -15,6 +15,11 @@ module Upman
15
15
 
16
16
  super(request, response)
17
17
 
18
+ unless is_authenticated(request)
19
+ response = not_authorized(response, "Request declined")
20
+ return response
21
+ end
22
+
18
23
  response = ok(response, perform_action)
19
24
  end
20
25
 
@@ -1,65 +1,84 @@
1
- module Upman
2
- module Server
3
- class BaseServlet < WEBrick::HTTPServlet::AbstractServlet
4
-
5
- include ::Upman::Utils::Helper
6
-
7
- attr_accessor :query, :response, :error_msg
8
-
9
- def initialize(server, *options)
10
- super(server, *options)
11
- end
12
-
13
- # rubocop:disable Naming/MethodName
14
- def do_GET(_request, response)
15
- # rubocop:enable Naming/MethodName
16
-
17
- info "Process API request #{_request.path}"
18
-
19
- @response = response
20
- @query = _request.query
21
- end
22
-
23
- def ok(response, body)
24
- response.status = 200
25
- response['Content-Type'] = 'application/json'
26
- response.body = body
27
- response
28
- end
29
-
30
- def bad_request(response, body)
31
- response.status = 400
32
- response['Content-Type'] = 'application/json'
33
- response.body = "{\"status\": \"bad_request\", \"message\": \"#{body}\"}"
34
- response
35
- end
36
-
37
- def get_param(key, validate, require = false)
38
- if @query.nil?
39
- return ''
40
- end
41
-
42
- unless @query.include? key
43
- unless require
44
- return ''
45
- else
46
- return nil
47
- end
48
- end
49
- unless validate.nil?
50
- if validate == 'date'
51
- begin
52
- @query[key] = DateTime.parse(@query[key])
53
- rescue
54
- msg = "Invalid content for param #{key}, expected type: date - found #{@query[key]}"
55
- bad_request(@response, msg)
56
- fail msg
57
- return false
58
- end
59
- end
60
- end
61
- @query[key]
62
- end
63
- end
64
- end
1
+ module Upman
2
+ module Server
3
+ class BaseServlet < WEBrick::HTTPServlet::AbstractServlet
4
+
5
+ include ::Upman::Utils::Helper
6
+
7
+ attr_accessor :query, :response, :error_msg
8
+
9
+ def initialize(server, *options)
10
+ super(server, *options)
11
+ end
12
+
13
+ # rubocop:disable Naming/MethodName
14
+ def do_GET(_request, response)
15
+ # rubocop:enable Naming/MethodName
16
+
17
+ info "Process API request #{_request.path}"
18
+
19
+ @response = response
20
+ @query = _request.query
21
+ end
22
+
23
+ def is_authenticated(request)
24
+ node_service = Upman::Service::Node.new
25
+ node_uuid = node_service.get_node_uuuid
26
+
27
+ info "Checking Authentication"
28
+ return true if request["x-upman-token"] == node_uuid
29
+
30
+ fail "Access denied"
31
+
32
+ false
33
+ end
34
+
35
+ def ok(response, body)
36
+ response.status = 200
37
+ response['Content-Type'] = 'application/json'
38
+ response.body = body
39
+ response
40
+ end
41
+
42
+ def not_authorized(response, body)
43
+ response.status = 401
44
+ response['Content-Type'] = 'application/json'
45
+ response.body = "{\"status\": \"not_authorized\", \"message\": \"#{body}\"}"
46
+ response
47
+ end
48
+
49
+ def bad_request(response, body)
50
+ response.status = 400
51
+ response['Content-Type'] = 'application/json'
52
+ response.body = "{\"status\": \"bad_request\", \"message\": \"#{body}\"}"
53
+ response
54
+ end
55
+
56
+ def get_param(key, validate, require = false)
57
+ if @query.nil?
58
+ return ''
59
+ end
60
+
61
+ unless @query.include? key
62
+ unless require
63
+ return ''
64
+ else
65
+ return nil
66
+ end
67
+ end
68
+ unless validate.nil?
69
+ if validate == 'date'
70
+ begin
71
+ @query[key] = DateTime.parse(@query[key])
72
+ rescue
73
+ msg = "Invalid content for param #{key}, expected type: date - found #{@query[key]}"
74
+ bad_request(@response, msg)
75
+ fail msg
76
+ return false
77
+ end
78
+ end
79
+ end
80
+ @query[key]
81
+ end
82
+ end
83
+ end
65
84
  end
@@ -0,0 +1,54 @@
1
+ module Upman
2
+ module Service
3
+ class InstallHistory
4
+
5
+ attr_accessor :since
6
+
7
+ def get(since)
8
+ @since = since
9
+
10
+ result = []
11
+
12
+ lines = fetch_history.split("\n")
13
+ lines.each do |line|
14
+ fill_up(result, line)
15
+ end
16
+ result.reverse!
17
+ end
18
+
19
+ private
20
+
21
+ def fetch_history
22
+ command = 'for x in $(ls -1t /var/log/dpkg.log*); do zcat -f $x |tac |grep -e " install " -e " upgrade " -e " remove "; done |awk -F ":a" \'{print $1 " :a" $2}\' |column -t'
23
+ `#{command}`
24
+ end
25
+
26
+ def fill_up(result, line)
27
+ command = parse_command(line)
28
+ return nil if command.empty?
29
+
30
+ if @since.instance_of?(DateTime)
31
+ if DateTime.parse(command[:datetime]) >= @since
32
+ result.append command
33
+ end
34
+ else
35
+ result.append command
36
+ end
37
+ end
38
+
39
+ def parse_command(command_line)
40
+ package = {}
41
+ regexp = /([0-9]{4}-[0-9]{2}-[0-9]{2})\s+([0-9]{2}:[0-9]{2}:[0-9]{2})\s+(upgrade|install|remove)\s+([\w\-+\.]+)\s+\:([a-z0-9]+)\s+([\w+:\.\-~<>]+)\s+([\w+:\.\-~<>]+)/
42
+ unless !(matches = command_line.match(regexp))
43
+ package[:datetime] = "#{matches[1]} #{matches[2]}"
44
+ package[:action] = matches[3]
45
+ package[:package] = matches[4]
46
+ package[:architecture] = matches[5]
47
+ package[:old_version] = (%w[<keine> <none>].include? matches[6]) ? nil : matches[6]
48
+ package[:target_version] = (%w[<keine> <none>].include? matches[7]) ? nil : matches[7]
49
+ end
50
+ package
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,24 @@
1
+ module Upman
2
+ module Service
3
+ class InstalledPackages
4
+
5
+ include ::Upman::Utils::Parser
6
+
7
+ def get(auto_installed)
8
+ result = []
9
+ extended_states = File.open('/var/lib/apt/extended_states', 'rb', &:read)
10
+ extended_states.split("\n\n").each do |chunk|
11
+ installed_packages = _get_hashed_values(chunk)
12
+ if auto_installed.empty?
13
+ result.append installed_packages
14
+ else
15
+ if installed_packages['auto_installed'] == auto_installed
16
+ result.append installed_packages
17
+ end
18
+ end
19
+ end
20
+ result
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,49 @@
1
+ module Upman
2
+ module Service
3
+ class Node
4
+
5
+ require 'securerandom'
6
+ require 'facter'
7
+ using SymbolizeHelper
8
+
9
+ attr_accessor :node_config
10
+
11
+ def initialize
12
+ @node_config = 'node.yml'
13
+ end
14
+
15
+
16
+ def get_node_uuuid
17
+ data = YAML::load_file(@node_config).deep_symbolize_keys
18
+ data[:uuid]
19
+ end
20
+
21
+ def generate_node_data
22
+ unless File.exist? @node_config
23
+ data = {
24
+ hostname: Socket.gethostbyname(Socket.gethostname).first,
25
+ uuid: SecureRandom.uuid,
26
+ }
27
+ File.write(@node_config, data.to_yaml)
28
+ end
29
+ update_node_data
30
+ end
31
+
32
+ def update_node_data
33
+ unless File.exist? @node_config
34
+ generate_node_data
35
+ end
36
+
37
+ data = YAML::load_file(@node_config).deep_symbolize_keys
38
+ data.merge!(
39
+ operatingsystem: Facter['operatingsystem'].value,
40
+ rubyversion: Facter['rubyversion'].value,
41
+ operatingsystemrelease: Facter['operatingsystemrelease'].value,
42
+ last_sync: DateTime.now
43
+ )
44
+ File.write(@node_config, data.to_yaml)
45
+ data
46
+ end
47
+ end
48
+ end
49
+ end
@@ -10,12 +10,12 @@ module Upman
10
10
  def check_connection
11
11
  response = self.get "status"
12
12
  if response.nil?
13
- false
13
+ return false
14
14
  end
15
15
 
16
16
  unless response.code == 200
17
17
  fail "Could not connect to API endpoint"
18
- false
18
+ return false
19
19
  end
20
20
  success "API Endpoint connected to Forman #{JSON.parse(response.body)["version"]} using API v#{JSON.parse(response.body)["api_version"]}."
21
21
  true
@@ -36,6 +36,8 @@ module Upman
36
36
  fail "Could not establish a secure connection to our API Endpoint"
37
37
  rescue RestClient::NotFound
38
38
  fail "API Endpoint route could not found"
39
+ rescue RestClient::InternalServerError
40
+ fail "API Endpoint reports error, ignore request"
39
41
  rescue Errno::ECONNREFUSED
40
42
  fail "Can not connect to Foreman instance on #{_url}"
41
43
  end
@@ -52,6 +54,8 @@ module Upman
52
54
  fail "Could not establish a secure connection to our API Endpoint"
53
55
  rescue RestClient::NotFound
54
56
  fail "API Endpoint route could not found"
57
+ rescue RestClient::InternalServerError
58
+ fail "API Endpoint reports error, ignore request"
55
59
  rescue Errno::ECONNREFUSED
56
60
  fail "Can not connect to your Foreman instance on #{_url}"
57
61
  end
@@ -0,0 +1,17 @@
1
+ module Upman
2
+ module Worker
3
+ class BaseWorker
4
+
5
+ include ::Upman::Utils::Helper
6
+
7
+ def run!
8
+ raise "No run! method defined"
9
+ end
10
+
11
+ def register
12
+ raise "No register method defined"
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,28 @@
1
+ module Upman
2
+ module Worker
3
+ class ReportInstallHistory < BaseWorker
4
+
5
+ def register
6
+ return self
7
+ end
8
+
9
+ def run!
10
+ while true
11
+ install_history_service = ::Upman::Service::InstallHistory.new
12
+ data = install_history_service.get("")
13
+
14
+ info "Report install history to API"
15
+
16
+
17
+ node_service = Upman::Service::Node.new
18
+ node_uuid = node_service.get_node_uuuid
19
+
20
+ api = ::Upman::Utils::Api.new
21
+ api.post("upman/node/install_history?uuid=#{node_uuid}", "{\"data\": #{data.to_json}}")
22
+
23
+ sleep(::Upman::Core::Config.daemon[:interval])
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ module Upman
2
+ module Worker
3
+ class ReportInstalledPackages < BaseWorker
4
+
5
+ def register
6
+ return self
7
+ end
8
+
9
+ def run!
10
+ while true
11
+ installed_package_service = ::Upman::Service::InstalledPackages.new
12
+ data = installed_package_service.get("1")
13
+ info "Report installed packages to API"
14
+
15
+
16
+ node_service = Upman::Service::Node.new
17
+ node_uuid = node_service.get_node_uuuid
18
+
19
+ #api = ::Upman::Utils::Api.new
20
+ #api.post("upman/node/installed_packages?uuid=#{node_uuid}","{\"data\": #{data.to_json}}")
21
+
22
+ sleep(::Upman::Core::Config.daemon[:interval])
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Upman
2
2
  class Version
3
- VERSION = '0.0.8.4'
3
+ VERSION = '0.0.8.5'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upman-daemon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8.4
4
+ version: 0.0.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Ehrig
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-21 00:00:00.000000000 Z
11
+ date: 2019-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coderay
@@ -97,12 +97,18 @@ files:
97
97
  - lib/upman/extensions/ping.rb
98
98
  - lib/upman/server/base_servlet.rb
99
99
  - lib/upman/server/socket.rb
100
+ - lib/upman/services/install_history.rb
101
+ - lib/upman/services/installed_packages.rb
102
+ - lib/upman/services/node.rb
100
103
  - lib/upman/utils/api.rb
101
104
  - lib/upman/utils/dynload.rb
102
105
  - lib/upman/utils/files.rb
103
106
  - lib/upman/utils/helper.rb
104
107
  - lib/upman/utils/parser.rb
105
108
  - lib/upman/utils/symbolize_helper.rb
109
+ - lib/upman/worker/base_worker.rb
110
+ - lib/upman/worker/report_install_history.rb
111
+ - lib/upman/worker/report_installed_packages.rb
106
112
  - lib/version.rb
107
113
  - upman.gemspec
108
114
  homepage: https://github.com/liKe2k1/upman