Class: RightScale::AgentIdentity

Inherits:
Object
  • Object
show all
Defined in:
lib/right_agent/agent_identity.rb

Overview

Agent identity management

Constant Summary collapse

SEPARATOR_EPOCH =

Cutover time at which agents began using new separator

Time.at(1256702400)
ID_SEPARATOR =

Separator used to differentiate between identity components when serialized

'-'
ID_SEPARATOR_OLD =

Separator used to differentiate between identity components prior to release 3.4

'*'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(prefix, agent_type, base_id, token = nil, separator = nil) ⇒ AgentIdentity

Generate new id

Parameters

prefix(String)

Prefix used to scope identity

agent_type(String)

Agent type (e.g. ‘core’, ‘instance’)

base_id(Integer)

Unique integer value

token(String)

Unique identity token, will be generated randomly if not provided

separator(String)

Character used to separate identity components, defaults to ID_SEPARATOR

Raise

RightScale::Exceptions::Argument

Invalid argument



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/right_agent/agent_identity.rb', line 51

def initialize(prefix, agent_type, base_id, token=nil, separator=nil)
  err = "Prefix cannot contain '#{ID_SEPARATOR}'" if prefix && prefix.include?(ID_SEPARATOR)
  err = "Prefix cannot contain '#{ID_SEPARATOR_OLD}'" if prefix && prefix.include?(ID_SEPARATOR_OLD)
  err = "Agent type cannot contain '#{ID_SEPARATOR}'" if agent_type.include?(ID_SEPARATOR)
  err = "Agent type cannot contain '#{ID_SEPARATOR_OLD}'" if agent_type.include?(ID_SEPARATOR_OLD)
  err = "Agent type cannot be nil" if agent_type.nil?
  err = "Agent type cannot be empty" if agent_type.size == 0
  err = "Base ID must be a positive integer" unless base_id.kind_of?(Integer) && base_id >= 0
  err = "Token cannot contain '#{ID_SEPARATOR}'" if token && token.include?(ID_SEPARATOR)
  err = "Token cannot contain '#{ID_SEPARATOR_OLD}'" if token && token.include?(ID_SEPARATOR_OLD)
  raise RightScale::Exceptions::Argument, err if err

  @separator  = separator || ID_SEPARATOR
  @prefix     = prefix
  @agent_type = agent_type
  @token      = token || self.class.generate
  @base_id    = base_id
end

Instance Attribute Details

#agent_typeObject (readonly)

Identity components



38
39
40
# File 'lib/right_agent/agent_identity.rb', line 38

def agent_type
  @agent_type
end

#base_idObject (readonly)

Identity components



38
39
40
# File 'lib/right_agent/agent_identity.rb', line 38

def base_id
  @base_id
end

#prefixObject (readonly)

Identity components



38
39
40
# File 'lib/right_agent/agent_identity.rb', line 38

def prefix
  @prefix
end

#tokenObject (readonly)

Identity components



38
39
40
# File 'lib/right_agent/agent_identity.rb', line 38

def token
  @token
end

Class Method Details

.compatible_serialized(serialized_id, version = 10) ⇒ Object

Convert serialized agent identity to format valid for given protocol version Ignore identity that is not in serialized AgentIdentity format

Parameters

serialized_id(String)

Serialized agent identity to be converted

version(Integer)

Target protocol version

Return

serialized_id(String)

Compatible serialized agent identity



120
121
122
123
124
125
126
127
# File 'lib/right_agent/agent_identity.rb', line 120

def self.compatible_serialized(serialized_id, version = 10)
  if version < 10
    serialized_id = "nanite-#{serialized_id}" if self.valid_parts?(serialized_id)
  else
    serialized_id = serialized_id[7..-1] if serialized_id =~ /^nanite-|^mapper-/
  end
  serialized_id
end

.generateObject

Generate unique identity

Return

id(String)

Random 128-bit hexadecimal string



74
75
76
77
78
# File 'lib/right_agent/agent_identity.rb', line 74

def self.generate
  bytes = Platform.rng.pseudorandom_bytes(16)
  #Transform into hex string
  id = bytes.unpack('H*')[0]
end

.instance_agent?(serialized_id) ⇒ Boolean

Check whether identity corresponds to an instance agent

Parameters

serialized_id(String)

Valid serialized agent identity (use ‘valid?’ to check first)

Return

(Boolean)

true if id corresponds to an instance agent, otherwise false

Returns:

  • (Boolean)


144
145
146
# File 'lib/right_agent/agent_identity.rb', line 144

def self.instance_agent?(serialized_id)
  parts(serialized_id)[1] == 'instance'
end

.parse(serialized_id) ⇒ Object

Instantiate by parsing given token

Parameters

serialized_id(String)

Valid serialized agent identity (use ‘valid?’ to check first)

Return

(AgentIdentity)

Corresponding agent identity

Raise

(RightScale::Exceptions::Argument)

Serialized agent identity is incorrect



101
102
103
104
105
106
107
108
109
# File 'lib/right_agent/agent_identity.rb', line 101

def self.parse(serialized_id)
  serialized_id = self.compatible_serialized(serialized_id)
  prefix, agent_type, token, bid, separator = parts(serialized_id)
  raise RightScale::Exceptions::Argument, "Invalid agent identity token" unless prefix && agent_type && token && bid
  base_id = bid.to_i
  raise RightScale::Exceptions::Argument, "Invalid agent identity token (Base ID)" unless base_id.to_s == bid

  AgentIdentity.new(prefix, agent_type, base_id, token, separator)
end

.valid?(serialized_id) ⇒ Boolean

Check validity of given serialized identity

Parameters

serialized_id(String)

Serialized identity to be tested

Return

(Boolean)

true if serialized identity is a valid, otherwise false

Returns:

  • (Boolean)


87
88
89
# File 'lib/right_agent/agent_identity.rb', line 87

def self.valid?(serialized_id)
  valid_parts?(self.compatible_serialized(serialized_id)) if serialized_id
end

Instance Method Details

#==(other) ⇒ Object

Comparison operator

Parameters

other(AgentIdentity)

Other agent identity

Return

(Boolean)

true if other is identical to self, otherwise false



163
164
165
166
167
168
169
# File 'lib/right_agent/agent_identity.rb', line 163

def ==(other)
  other.kind_of?(::RightScale::AgentIdentity) &&
  prefix     == other.prefix     &&
  agent_type == other.agent_type &&
  token      == other.token      &&
  base_id    == other.base_id
end

#instance_agent?Boolean

Check whether identity corresponds to an instance agent

Return

(Boolean)

true if id corresponds to an instance agent, otherwise false

Returns:

  • (Boolean)


133
134
135
# File 'lib/right_agent/agent_identity.rb', line 133

def instance_agent?
  agent_type == 'instance'
end

#to_sObject

String representation of identity

Return

(String)

Serialized identity



152
153
154
# File 'lib/right_agent/agent_identity.rb', line 152

def to_s
  "#{@prefix}#{@separator}#{@agent_type}#{@separator}#{@token}#{@separator}#{@base_id}"
end