Class: KSConnect::API::Plugin

Inherits:
Object
  • Object
show all
Includes:
Logs
Defined in:
lib/ksconnect/api/plugin.rb,
lib/ksconnect/api/plugin/data.rb,
lib/ksconnect/api/plugin/config.rb,
lib/ksconnect/api/plugin/domain.rb

Defined Under Namespace

Classes: Config, Data, Domain

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logs

included

Constructor Details

#initialize(name, main = false) ⇒ Plugin

Returns a new instance of Plugin.



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/ksconnect/api/plugin.rb', line 13

def initialize(name, main = false)
  @name = name
  @main_plugin = main
  @domains = {}

  Redis.current ||= Redis.new(driver: :hiredis)
  $redis ||= ConnectionPool.new(size: MAX_THREADS, timeout: 8) { Redis.current }

  load_domains
  subscribe_to_events
end

Instance Attribute Details

#configObject



25
26
27
# File 'lib/ksconnect/api/plugin.rb', line 25

def config
  @config ||= Config.new
end

#domainsObject

Returns the value of attribute domains.



9
10
11
# File 'lib/ksconnect/api/plugin.rb', line 9

def domains
  @domains
end

#nameObject (readonly)

Returns the value of attribute name.



10
11
12
# File 'lib/ksconnect/api/plugin.rb', line 10

def name
  @name
end

Instance Method Details

#configure {|config| ... } ⇒ Object

Yields:



29
30
31
# File 'lib/ksconnect/api/plugin.rb', line 29

def configure
  yield(config)
end

#domains_keyObject



112
113
114
115
# File 'lib/ksconnect/api/plugin.rb', line 112

def domains_key
  @domain_list_uuid ||= $redis.with { |redis| redis.hget("#{@name}:data", "domain_names") }
  "kloudsec_data:#{@domain_list_uuid}"
end

#load_domainsObject

This method loads the domain list from Redis, adding or removing domains as appropriate. Note that it does not update the ip address of existing domains.



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/ksconnect/api/plugin.rb', line 35

def load_domains
  # load domain list
  domain_to_ip = $redis.with { |redis| redis.hgetall(domains_key) }

  # add new domains
  new_domains = domain_to_ip.keys - @domains.values.map(&:name)
  new_domains.each { |domain_name| @domains[domain_name] = Domain.new(domain_name, domain_to_ip[domain_name], @name) }

  # remove old domains
  @domains.select! { |k, _| domain_to_ip.keys.include?(k) }
end

#perform_request(request) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/ksconnect/api/plugin.rb', line 86

def perform_request(request)
  request.stringify_keys!

  domain_name = request['domain_name']
  logger.warn "Invalid push request with no domain: #{request}" and return unless domain_name

  request_type = request['request_type']
  case request_type
    when 'initialize'
      @domains[domain_name] = Domain.new(domain_name, get_ip_for(domain_name), @name)
      config.on_initialize.call(request)
    when 'update'
      if @domains[domain_name]
        @domains[domain_name].update_ip_address
      else
        @domains[domain_name] = Domain.new(domain_name, get_ip_for(domain_name), @name)
      end
      config.on_update.call(request)
    when 'teardown'
      config.on_teardown.call(request)
      @domains.delete(domain_name)
    else
      raise "Invalid request type"
  end
end

#subscribe_to_eventsObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/ksconnect/api/plugin.rb', line 47

def subscribe_to_events
  KSConnect.channel("#{@name}:push") do |message|
    begin
      msg = JSON.parse(message)
    rescue Exception => e
      logger.error e
      logger.error "Error parsing message as JSON: #{message}"
      next
    end

    if %w(initialize update teardown).include? msg['request_type']
      perform_request(msg)
    else
      begin
        result = config.on_push.call(msg)
        update_action(msg["action_uuid"], :done, result) if msg["action_uuid"] && ENV['KSCONNECT_READ_ONLY'].nil?
      rescue => e
        update_action(msg["action_uuid"], :failed, "") if msg["action_uuid"] && ENV['KSCONNECT_READ_ONLY'].nil?
        raise e
      end
    end
  end
end

#update_action(action_id, state, body = "") ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ksconnect/api/plugin.rb', line 71

def update_action(action_id, state, body="")
  raise "Updating action with empty action_id" if action_id.nil? or action_id.empty?
  $redis.with do |redis|
    redis.multi do |redis_transaction|
      redis_transaction.mapped_hmset "kloudsec_data:#{action_id}", {
          plugin_name: @name,
          uuid: action_id,
          state: state,
          response: body,
      }
      redis_transaction.expire "kloudsec_data:#{action_id}", 300
    end
  end
end