Class: Bcome::Node::Base

Inherits:
Object
  • Object
show all
Includes:
Context, Attributes, LocalMetaDataFactory, RegistryManagement, WorkspaceCommands, WorkspaceMenu
Defined in:
lib/objects/node/base.rb

Direct Known Subclasses

Collection, Inventory::Base, Server::Base

Constant Summary collapse

DEFAULT_IDENTIFIER =
"bcome"

Constants included from LocalMetaDataFactory

LocalMetaDataFactory::META_DATA_FILE_PATH_PREFIX

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from RegistryManagement

#registry, #user_command_wrapper

Methods included from LocalMetaDataFactory

#do_create_metadata, #meta, #metadata, #metadata_for_namespace, #raw_metadata

Methods included from WorkspaceMenu

#item_spacing, #menu, #menu_item_spacing_length, #menu_items, #mode, #tab_spacing

Methods included from Attributes

#description, #filters, #identifier, #network_data, #network_driver, #recurse_hash_data_for_instance_var, #ssh_data, #ssh_driver, #type

Methods included from WorkspaceCommands

#back, #cd, #clear!, #disable, #disable!, #enable, #enable!, #interactive, #is_node_level_method?, #list_in_tree, #ls, #lsa, #method_in_registry?, #method_is_available_on_node?, #method_missing, #new_line, #parents, #ping, #pretty_description, #print_tree_view_for_resource, #resource_identifiers, #run, #tree, #tree_descriptions, #visual_hierarchy, #workon

Methods included from Context

#irb_workspace=, #is_current_context?, #previous_irb_workspace=

Constructor Details

#initialize(params) ⇒ Base

Returns a new instance of Base.



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/objects/node/base.rb', line 22

def initialize(params)
  @params = params
  @identifier = nil
  @description = nil
  @views = params[:views]
  @parent = params[:parent]
  @type = params[:type]
  @metadata = {}

  set_view_attributes if @views
  validate_attributes
  ::Bcome::Registry::Loader.instance.set_command_group_for_node(self)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Bcome::WorkspaceCommands

Instance Attribute Details

#paramsObject (readonly)

Returns the value of attribute params.



20
21
22
# File 'lib/objects/node/base.rb', line 20

def params
  @params
end

Class Method Details

.const_missing(constant) ⇒ Object



13
14
15
16
17
18
# File 'lib/objects/node/base.rb', line 13

def self.const_missing(constant)
  ## Hook for direct access to node level resources by constant name where
  ## cd ServerName should yield the same outcome as cd "ServerName"
  set_context  = ::IRB.CurrentContext.workspace.main
  return (set_context.resource_for_identifier(constant.to_s)) ? constant.to_s : super
end

Instance Method Details

#bootstrap?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/objects/node/base.rb', line 36

def bootstrap?
  false
end

#close_ssh_connectionsObject



211
212
213
214
215
216
# File 'lib/objects/node/base.rb', line 211

def close_ssh_connections
  machines.pmap do |machine|
    machine.close_ssh_connection
  end
  return
end

#collection?Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/objects/node/base.rb', line 40

def collection?
  false
end

#data_print_from_hash(data, heading) ⇒ Object



230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/objects/node/base.rb', line 230

def data_print_from_hash(data, heading)
  puts "\n#{heading.title}"
  puts ""

  if data.keys.any?
    data.each do |key, value|
      puts "#{key.to_s.resource_key}: #{value.to_s.informational}"
    end
  else
    puts "No values found".warning
  end
  puts ""
end

#enabled_menu_itemsObject



52
53
54
# File 'lib/objects/node/base.rb', line 52

def enabled_menu_items
  [:ls, :lsa, :workon, :enable, :disable, :enable!, :disable!, :run, :tree, :ping, :put, :rsync, :cd, :meta, :pack_metadata, :unpack_metadata, :registry, :interactive, :execute_script] 
end

#execute_local(command) ⇒ Object



225
226
227
228
# File 'lib/objects/node/base.rb', line 225

def execute_local(command)
  puts "(local) > #{command}"
  system(command)
end

#execute_script(script_name) ⇒ Object



90
91
92
93
94
95
96
97
# File 'lib/objects/node/base.rb', line 90

def execute_script(script_name)
  results = {}
  machines.pmap do |machine|
    command = machine.execute_script(script_name)
    results[machine.namespace] = command
  end
  results
end

#has_parent?Boolean

Returns:

  • (Boolean)


195
196
197
# File 'lib/objects/node/base.rb', line 195

def has_parent?
  !@parent.nil?
end

#has_proxy?Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/objects/node/base.rb', line 56

def has_proxy?
  ssh_driver.has_proxy?
end

#identifier=(new_identifier) ⇒ Object



60
61
62
# File 'lib/objects/node/base.rb', line 60

def identifier=(new_identifier)
  @identifier = new_identifier
end

#inventory?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/objects/node/base.rb', line 44

def inventory?
  false
end

#invoke(method_name, arguments = []) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/objects/node/base.rb', line 149

def invoke(method_name, arguments = [])
  if method_is_available_on_node?(method_name)
    if respond_to?(method_name)        
      # Invoke a method on node that's defined by the system
      begin
        if arguments && arguments.any?
          send(method_name, *arguments)
        else
          send(method_name)
        end
      rescue ArgumentError => e
        raise ::Bcome::Exception::ArgumentErrorInvokingMethodFromCommmandLine.new method_name + "error message - #{e.message}"
      end
    else
      # Invoke a user defined (registry) method
      command = user_command_wrapper.command_for_console_command_name(method_name.to_sym)
      command.execute(self, arguments)
    end
  else
    # Final crumb is neither a node level context nor an executable method on the penultimate node level context
    raise ::Bcome::Exception::InvalidBreadcrumb.new("Method '#{method_name}' is not available on bcome node of type #{self.class}, at namespace #{namespace}")
  end
end

#is_top_level_node?Boolean

Returns:

  • (Boolean)


199
200
201
# File 'lib/objects/node/base.rb', line 199

def is_top_level_node?
  !has_parent?
end

#keyed_namespaceObject



190
191
192
193
# File 'lib/objects/node/base.rb', line 190

def keyed_namespace
  splits = namespace.split(":") ; 
  splits[1..splits.size].join(":")
end

#list_attributesObject



203
204
205
206
207
208
209
# File 'lib/objects/node/base.rb', line 203

def list_attributes
  { 
    "Identifier": :identifier,
    "Description": :description,
    "Type": :type
  }
end

#list_keyObject



145
146
147
# File 'lib/objects/node/base.rb', line 145

def list_key
  :view
end

#namespaceObject



186
187
188
# File 'lib/objects/node/base.rb', line 186

def namespace
  "#{ parent ? "#{parent.namespace}:" : "" }#{identifier}"
end

#no_nodes?Boolean

Returns:

  • (Boolean)


133
134
135
# File 'lib/objects/node/base.rb', line 133

def no_nodes?
  !resources || resources.empty?
end

#nodes_loaded?Boolean

Returns:

  • (Boolean)


137
138
139
# File 'lib/objects/node/base.rb', line 137

def nodes_loaded?
  resources.any?
end

#open_ssh_connectionsObject



218
219
220
221
222
223
# File 'lib/objects/node/base.rb', line 218

def open_ssh_connections
  machines.pmap do |machine|
    machine.open_ssh_connection unless machine.has_ssh_connection?
  end
  return
end

#pack_metadataObject



99
100
101
# File 'lib/objects/node/base.rb', line 99

def 
  ::Bcome::Encryptor.instance.pack
end

#prompt_breadcrumbObject



182
183
184
# File 'lib/objects/node/base.rb', line 182

def prompt_breadcrumb
  "#{has_parent? ? "#{parent.prompt_breadcrumb}> " : "" }#{ is_current_context? ? (has_parent? ? identifier.terminal_prompt : identifier) : identifier}" 
end

#proxyObject



64
65
66
# File 'lib/objects/node/base.rb', line 64

def proxy
  ssh_driver.proxy
end

#put(local_path, remote_path) ⇒ Object



83
84
85
86
87
88
# File 'lib/objects/node/base.rb', line 83

def put(local_path, remote_path)
  resources.active.each do |resource|
    resource.put(local_path, remote_path)
  end
  return
end

#recurse_resource_for_identifier(identifier) ⇒ Object



177
178
179
180
# File 'lib/objects/node/base.rb', line 177

def recurse_resource_for_identifier(identifier)
  resource = resource_for_identifier(identifier)
  return resource ? resource : (has_parent? ? parent.recurse_resource_for_identifier(identifier) : nil)
end

#requires_description?Boolean

Returns:

  • (Boolean)


125
126
127
# File 'lib/objects/node/base.rb', line 125

def requires_description?
  true
end

#requires_type?Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/objects/node/base.rb', line 129

def requires_type?
  true
end

#resource_for_identifier(identifier) ⇒ Object



173
174
175
# File 'lib/objects/node/base.rb', line 173

def resource_for_identifier(identifier)
  resources.for_identifier(identifier)
end

#resourcesObject



141
142
143
# File 'lib/objects/node/base.rb', line 141

def resources
  @resources ||= ::Bcome::Node::Resources::Base.new
end

#rsync(local_path, remote_path) ⇒ Object



76
77
78
79
80
81
# File 'lib/objects/node/base.rb', line 76

def rsync(local_path, remote_path)
  resources.active.each do |resource|
    resource.rsync(local_path, remote_path)
  end   
  return
end

#scp(local_path, remote_path) ⇒ Object

TODO - why not do these in parallel?



69
70
71
72
73
74
# File 'lib/objects/node/base.rb', line 69

def scp(local_path, remote_path)
  resources.active.each do |resource|
    resource.put(local_path, remote_path)
  end
  return
end

#server?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/objects/node/base.rb', line 48

def server?
  false
end

#unpack_metadataObject



103
104
105
# File 'lib/objects/node/base.rb', line 103

def 
  ::Bcome::Encryptor.instance.unpack
end

#validate_attributesObject



107
108
109
110
111
# File 'lib/objects/node/base.rb', line 107

def validate_attributes
  validate_identifier 
  raise ::Bcome::Exception::MissingDescriptionOnView.new(@views.inspect) if requires_description? && !@description
  raise ::Bcome::Exception::MissingTypeOnView.new(@views.inspect) if requires_type? && !@type
end

#validate_identifierObject



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/objects/node/base.rb', line 113

def validate_identifier
  @identifier = DEFAULT_IDENTIFIER if is_top_level_node? && !@identifier && !is_a?(::Bcome::Node::Server::Base)

  @identifier = "NO-ID_#{Time.now.to_i}" unless @identifier

  #raise ::Bcome::Exception::MissingIdentifierOnView.new(@views.inspect) unless @identifier
  @identifier.gsub!(/\s/, "_") # Remove whitespace 
  @identifier.gsub!("-", "_") # change hyphens to undescores, hyphens don't play well in var names in irb

  #raise ::Bcome::Exception::InvalidIdentifier.new("'#{@identifier}' contains whitespace") if @identifier =~ /\s/
end