Class: Collins::PersistentState

Inherits:
Object
  • Object
show all
Includes:
State::Mixin, Util
Defined in:
lib/collins/persistent_state.rb

Overview

Provides state management via collins tags

Direct Known Subclasses

ProvisioningWorkflow

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from State::Mixin

#attribute_name, #expired?, #finished?, included, #method_missing, #plan, #reset!, #respond_to?, #state_name, #state_specification, #transition

Constructor Details

#initialize(collins_client, options = {}) ⇒ PersistentState

Returns a new instance of PersistentState.



14
15
16
17
18
# File 'lib/collins/persistent_state.rb', line 14

def initialize collins_client, options = {}
  @collins_client = collins_client
  @exec_type = :client
  @logger = get_logger({:logger => collins_client.logger}.merge(options).merge(:progname => 'Collins_PersistentState'))
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Collins::State::Mixin

Instance Attribute Details

#collins_clientObject (readonly)

Returns the value of attribute collins_client.



12
13
14
# File 'lib/collins/persistent_state.rb', line 12

def collins_client
  @collins_client
end

#exec_typeObject (readonly)

Returns the value of attribute exec_type.



12
13
14
# File 'lib/collins/persistent_state.rb', line 12

def exec_type
  @exec_type
end

#loggerObject (readonly)

Returns the value of attribute logger.



12
13
14
# File 'lib/collins/persistent_state.rb', line 12

def logger
  @logger
end

#pathObject (readonly)

Returns the value of attribute path.



12
13
14
# File 'lib/collins/persistent_state.rb', line 12

def path
  @path
end

Instance Method Details

#auth_header(username, password) ⇒ Object



87
88
89
90
# File 'lib/collins/persistent_state.rb', line 87

def auth_header username, password
  auth = Base64.strict_encode64("#{username}:#{password}")
  "Authorization: Basic #{auth}"
end

#format_spec_for_netcat(spec) ⇒ Array<Fixnum,String>

Returns padding for format string and json to use.

Returns:

  • (Array<Fixnum,String>)

    padding for format string and json to use



93
94
95
96
97
98
99
100
# File 'lib/collins/persistent_state.rb', line 93

def format_spec_for_netcat spec
  expected_timestamp_size = Time.now.utc.to_i.to_s.size
  spec.timestamp = '%s'
  actual_timestamp_size = spec.timestamp.to_s.size
  timestamp_padding = (expected_timestamp_size - actual_timestamp_size).abs
  json = spec.to_json
  [timestamp_padding, json]
end

#get_hostname_port(host) ⇒ Array<String,String>

Returns hostname and port.

Returns:

  • (Array<String,String>)

    hostname and port



102
103
104
105
# File 'lib/collins/persistent_state.rb', line 102

def get_hostname_port host
  host = URI.parse(host)
  [host.host, host.port.to_s]
end

#get_time_cmds(host) ⇒ Object



64
65
66
67
68
69
70
71
# File 'lib/collins/persistent_state.rb', line 64

def get_time_cmds host
  hostname, port = get_hostname_port host
  get_cmd = %q{printf 'GET /api/timestamp HTTP/1.0\r\n\r\n'}
  nc = sprintf('%s -i 1 %s %d', path, hostname, port)
  only_time = %q{grep -e '^[0-9]'}
  last_line = %q{tail -n 1}
  [get_cmd, nc, only_time, last_line]
end

#request_headers(username, password, length) ⇒ Object



77
78
79
80
81
82
83
84
85
# File 'lib/collins/persistent_state.rb', line 77

def request_headers username, password, length
  [
    "User-Agent: collins_state",
    auth_header(username, password),
    "Content-Type: application/x-www-form-urlencoded",
    "Content-Length: #{length}",
    "Connection: Close"
  ]
end

#request_line(tag) ⇒ Object



73
74
75
# File 'lib/collins/persistent_state.rb', line 73

def request_line tag
  "POST /api/asset/#{tag} HTTP/1.0"
end

#runObject



20
21
22
23
# File 'lib/collins/persistent_state.rb', line 20

def run
  self.class.managed_state(collins_client)
  self
end

#update_asset(asset, key, spec) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/collins/persistent_state.rb', line 43

def update_asset asset, key, spec
  username = collins_client.username
  password = collins_client.password
  host = collins_client.host
  tag = ::Collins::Util.get_asset_or_tag(asset).tag
  case @exec_type
  when :netcat
    netcat_command = [path, '-i', '1'] + get_hostname_port(host)
    timestamp_padding, json = format_spec_for_netcat spec
    body = "attribute=#{key};#{json}"
    length = body.size + timestamp_padding
    request = [request_line(tag)] + request_headers(username, password, length)
    request_string = request.join("\\r\\n") + "\\r\\n\\r\\n" + body
    current_time = 'TIMESTAMP=$(' + get_time_cmds(host).join(' | ') + ')'
    args = ['printf', request_string]
    "#{current_time}\n" + Escape.shell_command(args) + ' $TIMESTAMP | ' + Escape.shell_command(netcat_command)
  else
    super(asset, key, spec)
  end
end

#use_clientObject



30
31
32
33
34
# File 'lib/collins/persistent_state.rb', line 30

def use_client
  @path = nil
  @exec_type = :client
  self
end

#use_curl(path = nil) ⇒ Object

Deprecated.

Use #use_netcat instead. Replace in 0.3.0



26
27
28
# File 'lib/collins/persistent_state.rb', line 26

def use_curl path = nil
  use_netcat(path)
end

#use_netcat(path = nil) ⇒ Object



36
37
38
39
40
# File 'lib/collins/persistent_state.rb', line 36

def use_netcat path = nil
  @path = Collins::Option(path).get_or_else("nc")
  @exec_type = :netcat
  self
end