Class: Receiver::CrowbarRestAPIConnector

Inherits:
RestApiConnector show all
Defined in:
lib/receiver/crowbar_rest_api_connector.rb

Overview

Class linking to the crowbar Rest API.

Author:

  • tnoguer

Instance Attribute Summary

Attributes inherited from RestApiConnector

#auth_type, #dest_ip, #dest_port, #timeout

Instance Method Summary collapse

Methods inherited from RestApiConnector

#get_message_html, #launch_request, #launch_request_mock

Constructor Details

#initialize(logger) ⇒ CrowbarRestAPIConnector

Constructor of CrowbarRestApiConnector.

Parameters:

  • logger

    is the object that allow log all action and error , exception



18
19
20
21
22
23
24
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 18

def initialize(logger)
  file = File.new(File.dirname(__FILE__) + "/../../resources/cloudbox-server.conf", "r")
  json = file.read()
  conf = JSON.parse(json)
  super(conf["crowbar_server_ip"], conf["crowbar_server_port"], "DIGEST", conf["crowbar_user"], conf["crowbar_password"], 10000, logger)
  @logger.info("Receiver::CrowbarRestAPIConnector   initialize the parameters...")
end

Instance Method Details

#configure_proposal(vcluster_name, network, mask, vlan_id, cpu, ram, description) ⇒ Object

Set the configuration of proposal .

Parameters:

  • vcluster_name

    the name of cluster

  • network

    is network adress

  • mask

    is the cidr of network adress

  • vlan_id

    the value of VLANID

  • cpu

    is the weight of cpu

  • ram

    is the weight of ram memory

  • description

    is description of cluster

Returns:

  • Boolean true is successful and false if error

Author:

  • mbretaud



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 36

def configure_proposal(vcluster_name, network, mask, vlan_id, cpu, ram, description)
  barclamp_name = "cb#{vcluster_name}"
  proposal_name = "default"

  begin
    res = launch_request("GET", "/crowbar/#{barclamp_name}/1.0/proposals/#{proposal_name}", "")
    json = res.body
  rescue
    raise Common::ConfigureProposalError.new("Retrieve the data on the proposal '#{proposal_name}' of the barclamp '#{barclamp_name}'.")
  end

  begin
    p = JSON.parse(json)
    p['attributes'][barclamp]['conf']['name']=name
    p['attributes'][barclamp]['network']['address']=network
    p['attributes'][barclamp]['network']['mask']=mask
    p['attributes'][barclamp]['network']['idvlan']=vlan_id
    p['attributes'][barclamp]['resources']['cpu']=cpu
    p['attributes'][barclamp]['resources']['ram']=ram
    p['attributes'][barclamp]['description']=description

    json = p.to_json
  rescue
    raise Common::ConfigureProposalError.new("Error to set attributes of the barclamp '#{barclamp}'.")
  end

  path = "/crowbar/#{barclamp_name}/1.0/proposals/#{proposal_name}"

  begin
    res = launch_request("POST", path, json)

    if res.code != "302"
      raise Common::ConfigureProposalError.new("Code error '#{res.code}' of launching request POST on '#{path}' with data '#{json}'.")
    end
  rescue
    raise Common::ConfigureProposalError.new("Code error '#{res.code}' of launching request POST on '#{path}' with data '#{json}'.")
  end
end

#create_proposal(barclamp_name, proposal_name) ⇒ Object

create a proposal for a barclamp

Parameters:

  • barclamp_name

    the name of barclamp

  • proposal_name

    the name of proposal

Returns:

  • Boolean true is successful and false if error

Author:

  • mbretaud



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 81

def create_proposal(barclamp_name, proposal_name)
  path = "/crowbar/#{barclamp_name}/1.0/proposals"
  data = "{\"id\":\"#{proposal_name.strip}\"}"

  begin
    res = launch_request("PUT", path.strip, data.strip)
    if res.code != "200"
      raise Common::CreateProposalError.new("Create the proposal '#{proposal_name}' on the barclamp '#{barclamp_name}'.")
    end
    return true
  rescue
    raise Common::CreateProposalError.new("Create the proposal '#{proposal_name}' on the barclamp '#{barclamp_name}'.")
  end
  return true
end

#delete_node_proposal(node_name) ⇒ Object

Delete node in the proposal

Parameters:

  • node_name

    the name of node

Returns:

  • Boolean true is successful and false if error

Author:

  • mbretaud



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 102

def delete_node_proposal(node_name)
  dnode_name = nil
  hnode_name = nil

  if node_name[0, 1] == "d"
    dnode_name = node_name
    hnode_name = "h" + node_name[1..-1]
  else
    if node_name[0, 1] == "h"
      hnode_name = node_name
      dnode_name = "d" + node_name[1..-1]
    end
  end

  if dnode_name == nil && hnode_name == nil
    raise Common::DeleteNodeProposalError.new("The name of the name is not correct : '#{node_name}'.")
  end

  begin
    res = launch_request("GET", "/crowbar/barclamp/1.0/proposals/status", "")

    json = res.body
  rescue => e
    raise Common::DeleteNodeProposalError.new("Retrieve the list of barclamps and their status.")
  end

  p = JSON.parse(json)

  list_barclamps = Array.new
  if p['i18n'] != nil
    get_keys = p['i18n'].keys
    get_keys.each{|e|
      if p['i18n'][e]['proposal'] != nil
        proposal = p['i18n'][e]['proposal'].downcase
        barclamp = e
        list_barclamps << barclamp.gsub('_' + proposal, '')
      end
    }
  end

  list_barclamps.each{|barclamp|
    res = launch_request("GET", "/crowbar/#{barclamp}/1.0/proposals", "")

    if res.body != ""
      proposals = JSON.parse(res.body)

      if proposals.empty?
        puts "Warning: The barclamp '#{barclamp}' has no proposals!"
      else
        proposals.each { |proposal|
          #puts "Delete the node '#{node_name}' into the proposal '#{proposal}' of the barclamp '#{barclamp}'."
          path="/crowbar/#{barclamp}/1.0/proposals/#{proposal}"
          begin
            res = launch_request("GET", path, "")

            json = res.body
          rescue => e
            raise Common::DeleteNodeProposalError.new("Retrieve the data on the proposal '#{proposal}' of the barclamp '#{barclamp}'.")
          end

          #if $? != 0
          #  out="#{out}" + "Proposal '#{proposal}' of the barclamps '#{barclamp}' doesn't exists.\n"
          #else
            p = JSON.parse(json)

            attributes=p['attributes'][barclamp]
            deployment=p['deployment'][barclamp]

            if deployment['elements'] != nil
              get_keys = deployment['elements'].keys
              get_keys.each { |role|
                if deployment['elements'][role] != nil
                  deployment['elements'][role].each do |name|
                    if dnode_name == name
                      deployment['elements'][role].delete(dnode_name)
                    end
                    if hnode_name == name
                      deployment['elements'][role].delete(hnode_name)
                    end
                  end
                end
              }
            end

            if deployment['crowbar-committing'] != nil
              deployment['crowbar-committing'] = false
            end

            attributes = attributes.to_json.strip
            deployment = deployment.to_json.strip

            data_save = "barclamp=#{barclamp.strip}&name=#{proposal.strip}&proposal_attributes=#{attributes.strip}&proposal_deployment=#{deployment.strip}&submit=Save"
            data_apply = "barclamp=#{barclamp.strip}&name=#{proposal.strip}&proposal_attributes=#{attributes.strip}&proposal_deployment=#{deployment.strip}&submit=Apply"

            begin
              res = launch_request("POST", path, data_save)
              if res.code != "302"
                raise Common::DeleteNodeProposalError.new("Code error '#{res.code}' of launching request POST on '#{path}' with data '#{data_save}'.")
              end
            rescue => e
              puts "Error to Save : " + e.message
              raise Common::DeleteNodeProposalError.new("Error to Save : Code error '#{res.code}' of launching request POST on '#{path}' with data '#{data_save}'.")
            end
            res=nil
            if barclamp.strip =~ /^[c][b]+/ || barclamp.strip == "vcluster_core"
              begin
                path_post = "/crowbar/#{barclamp.strip}/1.0/proposals/#{proposal.strip}"

                res = launch_request("POST", path_post, data_apply)
                if res.code != "302"
                  raise Common::DeleteNodeProposalError.new("Code error '#{res.code}' of launching request POST on '#{path_post}' with data '#{data_apply}'.")
                end
              rescue => e
                raise Common::DeleteNodeProposalError.new("Error to Apply : Code error '#{res.code}' of launching request POST on '#{path_post}' with data '#{data_apply}'.")
              end
            end
          #end
        }
      end
    end
  }
end

#get_barclamps_listObject

Get a list of barclamps

Returns:

  • list The list of barclamps

Raises:

  • (ArgumentError)

    if an error occured while launching a request GET

Author:

  • mbretaud



230
231
232
233
234
235
236
237
238
239
240
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 230

def get_barclamps_list()
  begin
    res = launch_request("GET", "/crowbar/barclamp/1.0/proposals/status", "")

    json = res.body
  rescue => e
    raise Common::GetBarclampsListError.new("Retrieve the list of barclamps and their status.")
  end

  return JSON.parse(json)
end

#remove_nodes(vcluster_name) ⇒ Object

Remove node in proposal’s barclamp

Parameters:

  • vcluster_name

    the name of barclamp

Returns:

  • boolean true is successful and false if error

Author:

  • mbretaud



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 247

def remove_nodes(vcluster_name)
  barclamp_name = "cb#{vcluster_name}"
  proposal_name = "default"

  path_get = "/crowbar/#{barclamp_name}/1.0/proposals/#{proposal_name}"
  path_post = "/crowbar/#{barclamp_name}/1.0/proposals/#{proposal_name}"

  begin
    res = launch_request("GET", path_get, "")
    json = res.body
  rescue => e
    raise Common::RemoveNodesError.new("Retrieve the data on the proposal '#{proposal_name}' of the barclamp '#{barclamp_name}'.")
  end

  if res.code != "200"
    creation = true
    create_proposal(barclamp_name, proposal_name)

    begin
      res = launch_request("GET", path_get, "")
      json = res.body
    rescue => e
      raise Common::RemoveNodesError.new("The barclamp '#{barclamp_name}' don't exists.")
    end
  end

  begin
    p = JSON.parse(json)

    attributes=p['attributes'][barclamp_name]
    deployment=p['deployment'][barclamp_name]

    if deployment['elements'] != nil
      get_keys = deployment['elements'].keys
      get_keys.each { |role|
        deployment['elements'][role].each do |name|
          if name != nil
            deployment['elements'][role].delete(name)
          end
        end
      }
    end

    if deployment['crowbar-committing'] != nil
      deployment['crowbar-committing'] = false
    end

    attributes = attributes.to_json.strip
    deployment = deployment.to_json.strip

    data_save = "barclamp=#{barclamp_name}&name=#{proposal_name}&proposal_attributes=#{attributes}&proposal_deployment=#{deployment}&submit=Save"
  rescue => e
    raise Common::RemoveNodesError.new("Modify the body of the request.")
  end

  res=nil
  begin
    res = launch_request("POST", path_post, data_save)
    if res.code != "302"
      raise Common::RemoveNodesError.new("Code error '#{res.code}' of launching request POST on '#{path_post}' with data '#{data_save}'")
    end
  rescue => e
    raise Common::RemoveNodesError.new("Error to Save : " + e.message)
  end
end

#set_bios(node_name, bios_name) ⇒ Object

set bios name of node

Parameters:

  • node_name

    the name of node

  • bios_name

    the name of bios

Returns:

  • true is successful and false if error

Author:

  • mbretaud



319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 319

def set_bios(node_name, bios_name)
  node = node_name.split(".")
  node = node[0]

  begin
    res = launch_request("POST", "/nodes/#{node_name}/update", "alias=#{node}&bios=#{bios_name}&submit=Save")
    if res.code != "302"
      raise Common::NodeSetBiosError.new("Code error '#{res.code}' of launching request POST on '/nodes/#{node_name}/update' with data 'alias=#{node}&bios=#{bios_name}&submit=Save'.")
    end
    return true
  rescue => e
    raise Common::NodeSetBiosError.new("Impossible to set the node '#{node_name}' with the bios '#{bios_name}'.")
  end
end

#set_bios_raid(node_name, bios_name, raid_name) ⇒ Object

set raid JbodOnly or Raid10 and set bios on node

Parameters:

  • node_name

    the name of node

  • bios_name

    the name of bios

  • raid_name

    type of raid JbodOnly or Raid10

Returns:

  • true is successful and false if error

Author:

  • mbretaud



362
363
364
365
366
367
368
369
370
371
372
373
374
375
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 362

def set_bios_raid(node_name, bios_name, raid_name)
  node = node_name.split(".")
  node = node[0]

  begin
    res = launch_request("POST","/nodes/#{node_name}/update", "alias=#{node}&bios=#{bios_name}&raid=#{raid_name}&submit=Save")
    if res.code != "302"
      raise Common::NodeSetBiosRaidError.new("Code error '#{res.code}' of launching request POST on '/nodes/#{node_name}/update' with data 'alias=#{node}&bios=#{bios_name}&raid=#{raid_name}&submit=Save'")
    end
    return true
  rescue => e
    raise Common::NodeSetBiosRaidError.new("Impossible to set the node '#{node_name}' with the bios '#{bios_name}' and the raid '#{raid_name}'.")
  end
end

#set_raid(node_name, raid_name) ⇒ Object

set raid of node JbodOnly or Raid10

Parameters:

  • node_name

    the name of node

  • raid_name

    the name of raid JbodOnly or Raid10

Returns:

  • true is successful and false if error

Author:

  • mbretaud



340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 340

def set_raid(node_name, raid_name)
  node = node_name.split(".")
  node = node[0]

  begin
    res = launch_request("POST","/nodes/#{node_name}/update", "alias=#{node}&raid=#{raid_name}&submit=Save")
    if res.code != "302"
      raise Common::NodeSetRaidError.new("Code error '#{res.code}' of launching request POST on '/nodes/#{node_name}/update' with data 'alias=#{node}&raid=#{raid_name}&submit=Save'.")
    end
    return true
  rescue => e
    raise Common::NodeSetRaidError.new("Impossible to set the node '#{node_name}' with the raid '#{raid_name}'.")
  end
end

#vcluster_delete(vcluster_name) ⇒ Object

Delete a vcluster

Parameters:

  • vcluster_name

    The name of the vlcuster

Author:

  • mbretaud



381
382
383
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 381

def vcluster_delete(vcluster_name)
  # @todo
end

#vcluster_desallocate(vcluster_name) ⇒ Object

Desallocate a vcluster

Parameters:

  • vcluster_name

    The name of the vlcuster

Author:

  • mbretaud



389
390
391
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 389

def vcluster_desallocate(vcluster_name)
  # @todo
end

#verify_committed_barclamp(barclamp_name, list_machines) ⇒ Object

Verify a barclamp is commited with a good node

Parameters:

  • barclamp_name

    the name of barclamp

  • list_machines

    the list of node

Returns:

  • true is successful and false if error

Author:

  • mbretaud



400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
# File 'lib/receiver/crowbar_rest_api_connector.rb', line 400

def verify_committed_barclamp(barclamp_name, list_machines)
  proposal_name = "default"
  role="#{barclamp_name}-server"

  path_get = "/crowbar/#{barclamp_name}/1.0/proposals/#{proposal_name}"
  path_post = "/crowbar/#{barclamp_name}/1.0/proposals/#{proposal_name}"

  begin
    res = launch_request("GET", "/crowbar/barclamp/1.0/proposals/status", "")

    json = res.body
  rescue => e
    raise Common::VerifyCommittedBarclampError.new("GET the list of barclamps.")
  end

  p = JSON.parse(json)

  proposal_exists = false
  if p['i18n'] != nil
    get_keys = p['i18n'].keys
    get_keys.each{|e|
      if e.include? "#{barclamp_name.strip}"
        proposal_exists = true
      end
    }
  end

  if !proposal_exists
    creation = true
    if !create_proposal(barclamp_name, proposal_name)
      raise Common::VerifyCommittedBarclampError.new("The proposal '#{proposal_name}' could not be created on the barclamp '#{barclamp_name}'.")
    end
  end

  begin
    res = launch_request("GET", path_get, "")
    json = res.body
  rescue => e
    raise Common::VerifyCommittedBarclampError.new("Retrieve the data on the proposal '#{proposal_name}' of the barclamp '#{barclamp_name}'.")
  end

  begin
    p = JSON.parse(json)

    attributes=p['attributes'][barclamp_name]
    deployment=p['deployment'][barclamp_name]

    if creation
      deployment['elements'][role]=Array.new
    end

    list_machines_to_allocate = Array.new

    if deployment['elements'][role] != nil
      deployment['elements'][role].each{|machine_allocated|
        list_machines_to_allocate << machine_allocated
      }

      list_machines_to_allocate.each{|machine_allocated|
        deployment['elements'][role].delete(machine_allocated)
      }
    end

    list_machines.each do |machine|
      exists = false

      list_machines_to_allocate.each{|machine_allocated|
        if machine == machine_allocated
          exists = true
        end
      }

      if !exists
        list_machines_to_allocate << machine
      end
    end

    deployment['elements'][role] = Array.new
    deployment['elements'][role] = list_machines_to_allocate

    if deployment['crowbar-committing'] != nil
      deployment['crowbar-committing'] = false
    end

    attributes = attributes.to_json.strip
    deployment = deployment.to_json.strip

    data_save = "barclamp=#{barclamp_name.strip}&name=#{proposal_name.strip}&proposal_attributes=#{attributes.strip}&proposal_deployment=#{deployment.strip}&submit=Save"
    data_apply = "barclamp=#{barclamp_name.strip}&name=#{proposal_name.strip}&proposal_attributes=#{attributes.strip}&proposal_deployment=#{deployment.strip}&submit=Apply"

    path_post = "/crowbar/#{barclamp_name.strip}/1.0/proposals/#{proposal_name.strip}"
  rescue => e
    raise Common::VerifyCommittedBarclampError.new("Modify the body of the request.")
  end

  res=nil
  begin
    res = launch_request("POST", path_post, data_save)
    if res.code != "302"
      raise Common::VerifyCommittedBarclampError.new("Code error '#{res.code}' of launching request POST on '#{path_post}' with data '#{data_save}'.")
    end
  rescue => e
    raise Common::VerifyCommittedBarclampError.new("Launches of request POST on '#{path_post}' with data '#{data_save}' to Save.")
  end

  res=nil
  begin
    res = launch_request("POST", path_post, data_apply)
    if res.code != "302"
      raise Common::VerifyCommittedBarclampError.new("Code error '#{res.code}' of launching request POST on '#{path_post}' with data '#{data_apply}'.")
    end
  rescue => e
    raise Common::VerifyCommittedBarclampError.new("Launches of request POST on '#{path_post}' with data '#{data_save}' to Apply.")
  end

  return "Verify if the barclamp '#{barclamp_name}' is committed with the list of nodes...  [ OK ]\n"
end