stackmate 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/README.md +1 -0
  2. data/bin/stackmate.rb +9 -5
  3. data/lib/stackmate/intrinsic_functions.rb +3 -3
  4. data/lib/stackmate/metadata.rb +44 -0
  5. data/lib/stackmate/participants/cloudstack.rb +51 -10
  6. data/lib/stackmate/participants/cloudstack_affinitygroup.rb +4 -1
  7. data/lib/stackmate/participants/cloudstack_autoscalepolicy.rb +4 -1
  8. data/lib/stackmate/participants/cloudstack_autoscalevmgroup.rb +4 -1
  9. data/lib/stackmate/participants/cloudstack_autoscalevmprofile.rb +4 -1
  10. data/lib/stackmate/participants/cloudstack_condition.rb +4 -1
  11. data/lib/stackmate/participants/cloudstack_egressfirewallrule.rb +4 -1
  12. data/lib/stackmate/participants/cloudstack_firewallrule.rb +4 -1
  13. data/lib/stackmate/participants/cloudstack_globalloadbalancerrule.rb +4 -1
  14. data/lib/stackmate/participants/cloudstack_instancegroup.rb +4 -1
  15. data/lib/stackmate/participants/cloudstack_ipaddress.rb +4 -1
  16. data/lib/stackmate/participants/cloudstack_ipforwardingrule.rb +4 -1
  17. data/lib/stackmate/participants/cloudstack_iptonic.rb +4 -1
  18. data/lib/stackmate/participants/cloudstack_iso.rb +4 -1
  19. data/lib/stackmate/participants/cloudstack_lbhealthcheckpolicy.rb +4 -1
  20. data/lib/stackmate/participants/cloudstack_lbstickinesspolicy.rb +4 -1
  21. data/lib/stackmate/participants/cloudstack_loadbalancer.rb +4 -1
  22. data/lib/stackmate/participants/cloudstack_loadbalancerrule.rb +4 -1
  23. data/lib/stackmate/participants/cloudstack_network.rb +4 -1
  24. data/lib/stackmate/participants/cloudstack_networkacl.rb +4 -1
  25. data/lib/stackmate/participants/cloudstack_networkacllist.rb +4 -1
  26. data/lib/stackmate/participants/cloudstack_nictovirtualmachine.rb +5 -2
  27. data/lib/stackmate/participants/cloudstack_portforwardingrule.rb +4 -1
  28. data/lib/stackmate/participants/cloudstack_project.rb +4 -1
  29. data/lib/stackmate/participants/cloudstack_remoteaccessvpn.rb +4 -1
  30. data/lib/stackmate/participants/cloudstack_securitygroup.rb +4 -1
  31. data/lib/stackmate/participants/cloudstack_securitygroupegress.rb +4 -1
  32. data/lib/stackmate/participants/cloudstack_securitygroupingress.rb +4 -1
  33. data/lib/stackmate/participants/cloudstack_snapshot.rb +4 -1
  34. data/lib/stackmate/participants/cloudstack_snapshotpolicy.rb +4 -1
  35. data/lib/stackmate/participants/cloudstack_sshkeypair.rb +4 -1
  36. data/lib/stackmate/participants/cloudstack_staticnat.rb +4 -1
  37. data/lib/stackmate/participants/cloudstack_staticroute.rb +4 -1
  38. data/lib/stackmate/participants/cloudstack_tags.rb +4 -1
  39. data/lib/stackmate/participants/cloudstack_template.rb +4 -1
  40. data/lib/stackmate/participants/cloudstack_togloballoadbalancerrule.rb +4 -1
  41. data/lib/stackmate/participants/cloudstack_toloadbalancerrule.rb +4 -1
  42. data/lib/stackmate/participants/cloudstack_virtualmachine.rb +257 -281
  43. data/lib/stackmate/participants/cloudstack_virtualmachineops.rb +5 -2
  44. data/lib/stackmate/participants/cloudstack_vmsnapshot.rb +4 -1
  45. data/lib/stackmate/participants/cloudstack_volume.rb +4 -1
  46. data/lib/stackmate/participants/cloudstack_volumeops.rb +86 -90
  47. data/lib/stackmate/participants/cloudstack_vpc.rb +4 -1
  48. data/lib/stackmate/participants/cloudstack_vpnconnection.rb +4 -1
  49. data/lib/stackmate/participants/cloudstack_vpncustomergateway.rb +4 -1
  50. data/lib/stackmate/participants/cloudstack_vpngateway.rb +4 -1
  51. data/lib/stackmate/participants/cloudstack_vpnuser.rb +4 -1
  52. data/lib/stackmate/participants/common.rb +4 -2
  53. data/lib/stackmate/resolver.rb +28 -1
  54. data/lib/stackmate/stack_executor.rb +9 -5
  55. data/lib/stackmate/stack_server.rb +60 -0
  56. data/lib/stackmate/stackpi.rb +2 -7
  57. data/lib/stackmate/version.rb +1 -1
  58. data/lib/stackmate/waitcondition_server.rb +4 -6
  59. metadata +4 -2
data/README.md CHANGED
@@ -58,6 +58,7 @@ For example
58
58
  $ export APIKEY=upf7L-tvcHFCSYhKhw-45l9IfaKXNQSWf0nXyWye6eqOBpLT5TqN8XQGeuloV3LbSwD6zuucz22L233Nrqg2pg
59
59
  $ export SECKEY=9iSsuImdUxU0oumHu0p11li4IoUtwcvrSHcU63ZHS_y-4Iz3w5xPROzyjZTUXkhI9E7dy0r3vejzgCmaQfI-yw
60
60
  $ export URL="http://localhost:8080/client/api"
61
+ $ export WAIT_COND_URL_BASE="http://<my ip>:<some port>/"
61
62
  ```
62
63
 
63
64
  ## Sample Templates
data/bin/stackmate.rb CHANGED
@@ -3,7 +3,7 @@ require 'ruote/storage/hash_storage'
3
3
  require 'optparse'
4
4
  require 'stackmate'
5
5
  require 'stackmate/classmap'
6
- require 'stackmate/waitcondition_server'
6
+ require 'stackmate/stack_server'
7
7
  require 'stackmate/logging'
8
8
 
9
9
 
@@ -16,18 +16,22 @@ opt_parser = OptionParser.new do |opts|
16
16
  opts.on(:REQUIRED, "--template-file FILE", String, "Path to the file that contains the template") do |f|
17
17
  options[:file] = f
18
18
  end
19
- opts.on("-p", "--parameters [KEY1=VALUE1 KEY2=VALUE2..]", "Parameter values used to create the stack.") do |p|
19
+ opts.on("-p", "--parameters [KEY1=VALUE1;KEY2=VALUE2;..]", "Parameter values used to create the stack.") do |p|
20
20
  options[:params] = p
21
21
  puts p
22
22
  end
23
23
  options[:wait_conditions] = true
24
- opts.on("-n", "--no-wait-conditions", "Do not create any wait conditions") do
24
+ opts.on("-n", "--no-wait-conditions", "Do not create any wait conditions or metadata") do
25
25
  options[:wait_conditions] = false
26
26
  end
27
27
  options[:dry_run] = false
28
28
  opts.on("-r", "--dry-run", "Parse and pretend to execute but not actually do anything. Useful for validating the template") do
29
29
  options[:dry_run] = true
30
30
  end
31
+ options[:no_rollback] = false
32
+ opts.on("-R", "--no-rollback", "Do not rollback on failure") do
33
+ options[:no_rollback] = true
34
+ end
31
35
  opts.on("-h", "--help", "Show this message") do
32
36
  puts opts
33
37
  exit
@@ -58,7 +62,7 @@ end
58
62
  if options[:file] && stack_name != ''
59
63
  if options[:wait_conditions]
60
64
  Thread.new do
61
- StackMate::WaitConditionServer.run!
65
+ StackMate::StackServer.run!
62
66
  end
63
67
  end
64
68
  engine = Ruote::Dashboard.new(
@@ -73,7 +77,7 @@ if options[:file] && stack_name != ''
73
77
  StackMate.configure('NOOP') if options[:dry_run]
74
78
  opts = {}
75
79
  api_opts = {:APIKEY => "#{ENV['APIKEY']}", :SECKEY => "#{ENV['SECKEY']}", :URL => "#{ENV['URL']}" }
76
- p = StackMate::StackExecutor.new(options[:file], stack_name, options[:params], engine, options[:wait_conditions], api_opts, options[:timeout], options[:plugins])
80
+ p = StackMate::StackExecutor.new(options[:file], stack_name, options[:params], engine, options[:wait_conditions], api_opts, options[:timeout], options[:plugins], options[:no_rollback])
77
81
  p.launch()
78
82
  nil
79
83
  end
@@ -105,10 +105,10 @@ module StackMate
105
105
  def fn_base64(value, workitem)
106
106
  case value
107
107
  when String
108
- Base64.urlsafe_encode64(value)
108
+ Base64.strict_encode64(value)
109
109
  when Hash
110
- Base64.urlsafe_encode64(intrinsic(value, workitem))
110
+ Base64.strict_encode64(intrinsic(value, workitem))
111
111
  end
112
112
  end
113
113
  end
114
- end
114
+ end
@@ -0,0 +1,44 @@
1
+ require 'stackmate/logging'
2
+ module StackMate
3
+ class Metadata
4
+ include Logging
5
+ #nothing fancy
6
+ @@metadata_map = {}
7
+ def self.add_metadata(stack_id, logical_id, metadata)
8
+ #nothing fancy again, can refactor later if needed
9
+ if(!@@metadata_map.has_key?(stack_id))
10
+ @@metadata_map[stack_id] = {}
11
+ end
12
+
13
+ @@metadata_map[stack_id][logical_id] = metadata
14
+ #logger.debug("Successfully added metadata for resource #{logical_id} in stack #{stack_id}")
15
+ end
16
+
17
+ def self.get_metadata(stack_id,logical_id)
18
+ metadata = {}
19
+ if(@@metadata_map.has_key?(stack_id) && @@metadata_map[stack_id].has_key?(logical_id))
20
+ metadata = @@metadata_map[stack_id][logical_id]
21
+ end
22
+ metadata
23
+ end
24
+
25
+ #below may not be needed
26
+ def self.delete_metadata(stack_id, logical_id)
27
+ if(@@metadata_map.has_key?(stack_id) && @@metadata_map[stack_id].has_key?(logical_id))
28
+ @@metadata_map[stack_id].delete(logical_id)
29
+ end
30
+ #logger.debug("Successfully deleted metadata for resource #{logical_id} in stack #{stack_id}")
31
+ end
32
+
33
+ def self.clear_stack_metadata(stack_id)
34
+ if(@@metadata_map.has_key?(stack_id))
35
+ @@metadata_map.delete(stack_id)
36
+ end
37
+ end
38
+
39
+ def self.clear_metadata()
40
+ @@metadata_map.clear
41
+ end
42
+
43
+ end
44
+ end
@@ -5,7 +5,7 @@ require 'yaml'
5
5
  require 'stackmate/logging'
6
6
  require 'stackmate/intrinsic_functions'
7
7
  require 'stackmate/resolver'
8
-
8
+ require 'stackmate/metadata'
9
9
 
10
10
  module StackMate
11
11
 
@@ -35,6 +35,33 @@ module StackMate
35
35
  reply
36
36
  end
37
37
 
38
+ def set_metadata
39
+ resolved_metadata = recursive_resolve(workitem['Resources'][@name]['Metadata'],workitem)
40
+ stack_id = @resolved_names["CloudStack::StackId"]
41
+ data = {}
42
+ data['Description'] = workitem['Resources'][@name]['Description']
43
+ data['ResourceType'] = workitem['Resources'][@name]['Type']
44
+ data['LogicalResourceId'] = @name
45
+ data['Metadata'] = resolved_metadata.to_json
46
+ data['PhysicalResourceId'] = workitem[@name]['physical_id']
47
+ data['ResourceStatus'] = 'CREATE_COMPLETE'
48
+ data['ResourceStatusReason'] = 'StackMate_Resource'
49
+ data['StackId'] = @resolved_names["CloudStack::StackId"]
50
+ data['StackName'] = @resolved_names["CloudStack::StackName"]
51
+ data['LastUpdatedTimestamp'] = Time.new.to_i
52
+ respmetadata = {}
53
+ #TODO figure out a good workaround for this
54
+ respmetadata['RequestId'] = "be8e5b39-40b7-11e3-90b2-d9d62a5d5348"
55
+ data['ResponseMetadata'] = respmetadata
56
+ detail = {}
57
+ detail['StackResourceDetail'] = data
58
+ result = {}
59
+ result['DescribeStackResourceResult'] = detail
60
+ response = {}
61
+ response['DescribeStackResourceResponse'] = result
62
+ Metadata.add_metadata(stack_id,@name,response)
63
+ end
64
+
38
65
  protected
39
66
 
40
67
  def set_tags(tags,resourceId,resourceType)
@@ -80,7 +107,7 @@ module StackMate
80
107
  #resp = @client.send(cmd, args)
81
108
  resp = @client.api_call(cmd,args)
82
109
  jobid = resp['jobid'] if resp
83
- resp = api_poll(jobid, 60, 5) if jobid
110
+ resp = api_poll(jobid, 3, 3) if jobid
84
111
  return resp
85
112
  rescue => e
86
113
  logger.error("Failed to make request #{cmd} to CloudStack server while creating resource #{@name}")
@@ -93,19 +120,33 @@ module StackMate
93
120
  end
94
121
 
95
122
  def api_poll (jobid, num, period)
96
- i = 0
97
- loop do
98
- break if i > num
99
- #resp = @client.queryAsyncJobResult({'jobid' => jobid})
123
+ # i = 0
124
+ # loop do
125
+ # break if i > num
126
+ # #resp = @client.queryAsyncJobResult({'jobid' => jobid})
127
+ # resp = @client.api_call("queryAsyncJobResult",{'jobid' => jobid})
128
+ # if resp
129
+ # return resp['jobresult'] if resp['jobstatus'] == 1
130
+ # return {'error' => true} if resp['jobstatus'] == 2
131
+ # end
132
+ # sleep(period)
133
+ # i += 1
134
+ # end
135
+ # return {}
136
+ jobstatus = 0
137
+ jobresult = {}
138
+ iters = 100000 #to avoid infiinte loop
139
+ while (jobstatus == 0 && iters > 0) do
140
+ iters -= 1
100
141
  resp = @client.api_call("queryAsyncJobResult",{'jobid' => jobid})
101
142
  if resp
102
- return resp['jobresult'] if resp['jobstatus'] == 1
103
- return {'error' => true} if resp['jobstatus'] == 2
143
+ jobstatus = resp['jobstatus']
144
+ jobresult = resp['jobresult']
104
145
  end
105
146
  sleep(period)
106
- i += 1
107
147
  end
108
- return {}
148
+ return jobresult if jobstatus == 1
149
+ return {'error' => true}
109
150
  end
110
151
 
111
152
  end
@@ -22,6 +22,7 @@ module StackMate
22
22
  p args
23
23
  result_obj = make_async_request('createAffinityGroup',args)
24
24
  resource_obj = result_obj['AffinityGroup'.downcase]
25
+
25
26
  #doing it this way since it is easier to change later, rather than cloning whole object
26
27
  resource_obj.each_key do |k|
27
28
  val = resource_obj[k]
@@ -31,6 +32,7 @@ module StackMate
31
32
  workitem[@name][k] = val
32
33
  end
33
34
  set_tags(@props['tags'],workitem[@name]['physical_id'],"AffinityGroup") if @props.has_key?('tags')
35
+ set_metadata if workitem['Resources'][@name].has_key?('Metadata')
34
36
  workitem['ResolvedNames'][@name] = name_cs
35
37
  workitem['IdMap'][workitem[@name]['physical_id']] = @name
36
38
 
@@ -55,6 +57,7 @@ module StackMate
55
57
  if (!(result_obj['error'] == true))
56
58
  logger.info("Successfully deleted resource #{@name}")
57
59
  else
60
+ workitem[@name]['delete_error'] = true
58
61
  logger.info("CloudStack error while deleting resource #{@name}")
59
62
  end
60
63
  else
@@ -119,4 +122,4 @@ module StackMate
119
122
  end
120
123
  end
121
124
  end
122
-
125
+
@@ -21,6 +21,7 @@ module StackMate
21
21
  p args
22
22
  result_obj = make_async_request('createAutoScalePolicy',args)
23
23
  resource_obj = result_obj['AutoScalePolicy'.downcase]
24
+
24
25
  #doing it this way since it is easier to change later, rather than cloning whole object
25
26
  resource_obj.each_key do |k|
26
27
  val = resource_obj[k]
@@ -30,6 +31,7 @@ module StackMate
30
31
  workitem[@name][k] = val
31
32
  end
32
33
  set_tags(@props['tags'],workitem[@name]['physical_id'],"AutoScalePolicy") if @props.has_key?('tags')
34
+ set_metadata if workitem['Resources'][@name].has_key?('Metadata')
33
35
  workitem['ResolvedNames'][@name] = name_cs
34
36
  workitem['IdMap'][workitem[@name]['physical_id']] = @name
35
37
 
@@ -54,6 +56,7 @@ module StackMate
54
56
  if (!(result_obj['error'] == true))
55
57
  logger.info("Successfully deleted resource #{@name}")
56
58
  else
59
+ workitem[@name]['delete_error'] = true
57
60
  logger.info("CloudStack error while deleting resource #{@name}")
58
61
  end
59
62
  else
@@ -110,4 +113,4 @@ module StackMate
110
113
  end
111
114
  end
112
115
  end
113
-
116
+
@@ -18,6 +18,7 @@ module StackMate
18
18
  p args
19
19
  result_obj = make_async_request('enableAutoScaleVmGroup',args)
20
20
  resource_obj = result_obj['AutoScaleVmGroup'.downcase]
21
+
21
22
  #doing it this way since it is easier to change later, rather than cloning whole object
22
23
  resource_obj.each_key do |k|
23
24
  val = resource_obj[k]
@@ -27,6 +28,7 @@ module StackMate
27
28
  workitem[@name][k] = val
28
29
  end
29
30
  set_tags(@props['tags'],workitem[@name]['physical_id'],"AutoScaleVmGroup") if @props.has_key?('tags')
31
+ set_metadata if workitem['Resources'][@name].has_key?('Metadata')
30
32
  workitem['ResolvedNames'][@name] = name_cs
31
33
  workitem['IdMap'][workitem[@name]['physical_id']] = @name
32
34
 
@@ -51,6 +53,7 @@ module StackMate
51
53
  if (!(result_obj['error'] == true))
52
54
  logger.info("Successfully deleted resource #{@name}")
53
55
  else
56
+ workitem[@name]['delete_error'] = true
54
57
  logger.info("CloudStack error while deleting resource #{@name}")
55
58
  end
56
59
  else
@@ -83,4 +86,4 @@ module StackMate
83
86
  end
84
87
  end
85
88
  end
86
-
89
+
@@ -24,6 +24,7 @@ module StackMate
24
24
  p args
25
25
  result_obj = make_async_request('createAutoScaleVmProfile',args)
26
26
  resource_obj = result_obj['AutoScaleVmProfile'.downcase]
27
+
27
28
  #doing it this way since it is easier to change later, rather than cloning whole object
28
29
  resource_obj.each_key do |k|
29
30
  val = resource_obj[k]
@@ -33,6 +34,7 @@ module StackMate
33
34
  workitem[@name][k] = val
34
35
  end
35
36
  set_tags(@props['tags'],workitem[@name]['physical_id'],"AutoScaleVmProfile") if @props.has_key?('tags')
37
+ set_metadata if workitem['Resources'][@name].has_key?('Metadata')
36
38
  workitem['ResolvedNames'][@name] = name_cs
37
39
  workitem['IdMap'][workitem[@name]['physical_id']] = @name
38
40
 
@@ -57,6 +59,7 @@ module StackMate
57
59
  if (!(result_obj['error'] == true))
58
60
  logger.info("Successfully deleted resource #{@name}")
59
61
  else
62
+ workitem[@name]['delete_error'] = true
60
63
  logger.info("CloudStack error while deleting resource #{@name}")
61
64
  end
62
65
  else
@@ -137,4 +140,4 @@ module StackMate
137
140
  end
138
141
  end
139
142
  end
140
-
143
+
@@ -22,6 +22,7 @@ module StackMate
22
22
  p args
23
23
  result_obj = make_async_request('createCondition',args)
24
24
  resource_obj = result_obj['Condition'.downcase]
25
+
25
26
  #doing it this way since it is easier to change later, rather than cloning whole object
26
27
  resource_obj.each_key do |k|
27
28
  val = resource_obj[k]
@@ -31,6 +32,7 @@ module StackMate
31
32
  workitem[@name][k] = val
32
33
  end
33
34
  set_tags(@props['tags'],workitem[@name]['physical_id'],"Condition") if @props.has_key?('tags')
35
+ set_metadata if workitem['Resources'][@name].has_key?('Metadata')
34
36
  workitem['ResolvedNames'][@name] = name_cs
35
37
  workitem['IdMap'][workitem[@name]['physical_id']] = @name
36
38
 
@@ -55,6 +57,7 @@ module StackMate
55
57
  if (!(result_obj['error'] == true))
56
58
  logger.info("Successfully deleted resource #{@name}")
57
59
  else
60
+ workitem[@name]['delete_error'] = true
58
61
  logger.info("CloudStack error while deleting resource #{@name}")
59
62
  end
60
63
  else
@@ -119,4 +122,4 @@ module StackMate
119
122
  end
120
123
  end
121
124
  end
122
-
125
+
@@ -25,6 +25,7 @@ module StackMate
25
25
  p args
26
26
  result_obj = make_async_request('createEgressFirewallRule',args)
27
27
  resource_obj = result_obj['EgressFirewallRule'.downcase]
28
+
28
29
  #doing it this way since it is easier to change later, rather than cloning whole object
29
30
  resource_obj.each_key do |k|
30
31
  val = resource_obj[k]
@@ -34,6 +35,7 @@ module StackMate
34
35
  workitem[@name][k] = val
35
36
  end
36
37
  set_tags(@props['tags'],workitem[@name]['physical_id'],"EgressFirewallRule") if @props.has_key?('tags')
38
+ set_metadata if workitem['Resources'][@name].has_key?('Metadata')
37
39
  workitem['ResolvedNames'][@name] = name_cs
38
40
  workitem['IdMap'][workitem[@name]['physical_id']] = @name
39
41
 
@@ -58,6 +60,7 @@ module StackMate
58
60
  if (!(result_obj['error'] == true))
59
61
  logger.info("Successfully deleted resource #{@name}")
60
62
  else
63
+ workitem[@name]['delete_error'] = true
61
64
  logger.info("CloudStack error while deleting resource #{@name}")
62
65
  end
63
66
  else
@@ -146,4 +149,4 @@ module StackMate
146
149
  end
147
150
  end
148
151
  end
149
-
152
+
@@ -25,6 +25,7 @@ module StackMate
25
25
  p args
26
26
  result_obj = make_async_request('createFirewallRule',args)
27
27
  resource_obj = result_obj['FirewallRule'.downcase]
28
+
28
29
  #doing it this way since it is easier to change later, rather than cloning whole object
29
30
  resource_obj.each_key do |k|
30
31
  val = resource_obj[k]
@@ -34,6 +35,7 @@ module StackMate
34
35
  workitem[@name][k] = val
35
36
  end
36
37
  set_tags(@props['tags'],workitem[@name]['physical_id'],"FirewallRule") if @props.has_key?('tags')
38
+ set_metadata if workitem['Resources'][@name].has_key?('Metadata')
37
39
  workitem['ResolvedNames'][@name] = name_cs
38
40
  workitem['IdMap'][workitem[@name]['physical_id']] = @name
39
41
 
@@ -58,6 +60,7 @@ module StackMate
58
60
  if (!(result_obj['error'] == true))
59
61
  logger.info("Successfully deleted resource #{@name}")
60
62
  else
63
+ workitem[@name]['delete_error'] = true
61
64
  logger.info("CloudStack error while deleting resource #{@name}")
62
65
  end
63
66
  else
@@ -146,4 +149,4 @@ module StackMate
146
149
  end
147
150
  end
148
151
  end
149
-
152
+
@@ -26,6 +26,7 @@ module StackMate
26
26
  p args
27
27
  result_obj = make_async_request('createGlobalLoadBalancerRule',args)
28
28
  resource_obj = result_obj['GlobalLoadBalancerRule'.downcase]
29
+
29
30
  #doing it this way since it is easier to change later, rather than cloning whole object
30
31
  resource_obj.each_key do |k|
31
32
  val = resource_obj[k]
@@ -35,6 +36,7 @@ module StackMate
35
36
  workitem[@name][k] = val
36
37
  end
37
38
  set_tags(@props['tags'],workitem[@name]['physical_id'],"GlobalLoadBalancerRule") if @props.has_key?('tags')
39
+ set_metadata if workitem['Resources'][@name].has_key?('Metadata')
38
40
  workitem['ResolvedNames'][@name] = name_cs
39
41
  workitem['IdMap'][workitem[@name]['physical_id']] = @name
40
42
 
@@ -59,6 +61,7 @@ module StackMate
59
61
  if (!(result_obj['error'] == true))
60
62
  logger.info("Successfully deleted resource #{@name}")
61
63
  else
64
+ workitem[@name]['delete_error'] = true
62
65
  logger.info("CloudStack error while deleting resource #{@name}")
63
66
  end
64
67
  else
@@ -155,4 +158,4 @@ module StackMate
155
158
  end
156
159
  end
157
160
  end
158
-
161
+