Class: VCloudCloud::VCloudClient

Inherits:
Object
  • Object
show all
Defined in:
lib/cloud/vcloud/vcd_client.rb

Constant Summary collapse

VCLOUD_VERSION_NUMBER =
'5.5'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(vcd_settings, logger) ⇒ VCloudClient

Returns a new instance of VCloudClient.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/cloud/vcloud/vcd_client.rb', line 17

def initialize(vcd_settings, logger)
  @logger = logger
  @url  = vcd_settings['url']
  @user = vcd_settings['user']
  @pass = vcd_settings['password']
  @entities = vcd_settings['entities']

  control = @entities['control'] || {}
  @wait_max       = control['wait_max'] || WAIT_MAX
  @wait_delay     = control['wait_delay'] || WAIT_DELAY
  @retry_max      = control['retry_max'] || RETRY_MAX
  @retry_delay    = control['retry_delay'] || RETRY_DELAY
  @cookie_timeout = control['cookie_timeout'] || COOKIE_TIMEOUT

  @cache = Cache.new
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



13
14
15
# File 'lib/cloud/vcloud/vcd_client.rb', line 13

def logger
  @logger
end

Instance Method Details

#catalog(catalog_type) ⇒ Object



70
71
72
73
74
# File 'lib/cloud/vcloud/vcd_client.rb', line 70

def catalog(catalog_type)
  catalog_link = org.catalog_link catalog_name(catalog_type)
  raise ObjectNotFoundError, "Invalid catalog type: #{catalog_type}" unless catalog_link
  resolve_link catalog_link
end

#catalog_item(catalog_type, name, type) ⇒ Object

TODO we can discard type parameter since name should be the unique identifier of a item in one catalog.



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/cloud/vcloud/vcd_client.rb', line 78

def catalog_item(catalog_type, name, type)
  cat = catalog catalog_type
  items = cat.catalog_items name
  result = nil
  items.any? do |item|
    object = resolve_link item
    result = object if object.entity['type'] == type
    result
  end if items
  result
end

#catalog_name(catalog_type) ⇒ Object

catalog_type should be either :vapp or :media



66
67
68
# File 'lib/cloud/vcloud/vcd_client.rb', line 66

def catalog_name(catalog_type)
  @entities["#{catalog_type.to_s}_catalog"]
end

#flush_cacheObject



189
190
191
# File 'lib/cloud/vcloud/vcd_client.rb', line 189

def flush_cache
  @cache.clear
end

#invoke(method, path, options = {}) ⇒ Object



122
123
124
125
126
127
# File 'lib/cloud/vcloud/vcd_client.rb', line 122

def invoke(method, path, options = {})
  session

  response = send_request method, path, options
  (options[:no_wrap] || response.code == 204) ? response : wrap_response(response)
end

#invoke_and_wait(*args) ⇒ Object



134
135
136
# File 'lib/cloud/vcloud/vcd_client.rb', line 134

def invoke_and_wait(*args)
  wait_task invoke(*args)
end

#media(name) ⇒ Object



90
91
92
93
94
95
# File 'lib/cloud/vcloud/vcd_client.rb', line 90

def media(name)
  catalog_media = catalog_item :media, name, VCloudSdk::Xml::MEDIA_TYPE[:MEDIA]
  raise ObjectNotFoundError, "Invalid catalog media: #{name}" unless catalog_media
  media = resolve_link catalog_media.entity
  [media, catalog_media]
end

#media_catalog_nameObject



46
47
48
# File 'lib/cloud/vcloud/vcd_client.rb', line 46

def media_catalog_name
  @entities['media_catalog']
end

#orgObject



50
51
52
53
54
55
# File 'lib/cloud/vcloud/vcd_client.rb', line 50

def org
  @cache.get :org do
    session
    resolve_link @org_link
  end
end

#org_nameObject



34
35
36
# File 'lib/cloud/vcloud/vcd_client.rb', line 34

def org_name
  @entities['organization']
end

#reload(object) ⇒ Object



118
119
120
# File 'lib/cloud/vcloud/vcd_client.rb', line 118

def reload(object)
  resolve_link object.href
end

#resolve_entity(id) ⇒ Object



111
112
113
114
115
116
# File 'lib/cloud/vcloud/vcd_client.rb', line 111

def resolve_entity(id)
  session
  entity = invoke :get, "#{@entity_resolver_link.href}#{id}"
  raise ObjectNotFoundError, "Invalid entity urn: #{id}" unless entity
  resolve_link entity.link
end


107
108
109
# File 'lib/cloud/vcloud/vcd_client.rb', line 107

def resolve_link(link)
  invoke :get, link
end

#timed_loop(raise_exception = true) ⇒ Object

Raises:



180
181
182
183
184
185
186
187
# File 'lib/cloud/vcloud/vcd_client.rb', line 180

def timed_loop(raise_exception = true)
  start_time = Time.now
  while Time.now - start_time < @wait_max
    yield
    sleep @wait_delay
  end
  raise TimeoutError if raise_exception
end

#upload_stream(url, size, stream, options = {}) ⇒ Object



129
130
131
132
# File 'lib/cloud/vcloud/vcd_client.rb', line 129

def upload_stream(url, size, stream, options = {})
  session
  FileUploader.upload url, size, stream, options.merge({ :cookie => @cookie, :authorization => @auth_token })
end

#vapp_by_name(name) ⇒ Object



97
98
99
100
101
102
103
104
105
# File 'lib/cloud/vcloud/vcd_client.rb', line 97

def vapp_by_name(name)
  vdc_link = org.vdc_link vdc_name
  raise ObjectNotFoundError, "Invalid virtual datacenter name: #{vdc_name}" unless vdc_link
  vdc_obj = resolve_link vdc_link
  node = vdc_obj.get_vapp name
  raise ObjectNotFoundError, "vApp #{name} does not exist" unless node
  @logger.debug "VAPP_BY_NAME - get a vapp name"
  resolve_link node.href
end

#vapp_catalog_nameObject



42
43
44
# File 'lib/cloud/vcloud/vcd_client.rb', line 42

def vapp_catalog_name
  @entities['vapp_catalog']
end

#vdcObject



57
58
59
60
61
62
63
# File 'lib/cloud/vcloud/vcd_client.rb', line 57

def vdc
  @cache.get :vdc do
    vdc_link = org.vdc_link vdc_name
    raise ObjectNotFoundError, "Invalid virtual datacenter name: #{vdc_name}" unless vdc_link
    resolve_link vdc_link
  end
end

#vdc_nameObject



38
39
40
# File 'lib/cloud/vcloud/vcd_client.rb', line 38

def vdc_name
  @entities['virtual_datacenter']
end

#wait_entity(entity, accept_failure = false) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/cloud/vcloud/vcd_client.rb', line 152

def wait_entity(entity, accept_failure = false)
  prerunning_tasks = entity.prerunning_tasks
  prerunning_tasks.each do |task|
    wait_task task, accept_failure
  end if prerunning_tasks && !prerunning_tasks.empty?

  running_tasks = entity.running_tasks
  running_tasks.each do |task|
    wait_task task, accept_failure
  end if running_tasks && !running_tasks.empty?

  entity = reload entity

  # verify all tasks succeeded
  unless entity.tasks.nil? || entity.tasks.empty?
    failed_tasks = entity.tasks.find_all { |task| task.status.downcase != VCloudSdk::Xml::TASK_STATUS[:SUCCESS] }
    unless failed_tasks.empty?
      @logger.debug "Failed tasks: #{failed_tasks}"
      unless accept_failure
        failed_tasks_info = failed_tasks.map { |t| "Task #{t.urn} #{t.operation}, Details:#{t.details}" }
        raise "Some tasks failed: #{failed_tasks_info.join('; ')}"
      end
    end
  end

  entity
end

#wait_task(task, accept_failure = false) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/cloud/vcloud/vcd_client.rb', line 138

def wait_task(task, accept_failure = false)
  timed_loop do
    task = reload task
    status = task.status.downcase
    @logger.debug "WAIT TASK #{task.urn} #{task.operation} #{status}"
    return task if status == VCloudSdk::Xml::TASK_STATUS[:SUCCESS]
    if [:ABORTED, :ERROR, :CANCELED].any? { |s| status == VCloudSdk::Xml::TASK_STATUS[s] }
      return task if accept_failure
      raise "Task #{task.urn} #{task.operation} completed unsuccessfully, Details:#{task.details}"
    end
  end
  task
end