Class: EmbCartController

Inherits:
BaseController show all
Includes:
CartridgeHelper, LegacyBrokerHelper
Defined in:
app/controllers/emb_cart_controller.rb

Constant Summary

Constants inherited from BaseController

BaseController::API_VERSION, BaseController::SUPPORTED_API_VERSIONS

Instance Method Summary collapse

Methods included from CartridgeHelper

#check_cartridge_type, #get_cartridges

Methods included from LegacyBrokerHelper

#get_cached

Methods included from UserActionLogger

#get_action_logger, #log_action

Instance Method Details

#createObject

POST /domains//applications//cartridges



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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
# File 'app/controllers/emb_cart_controller.rb', line 83

def create
  domain_id = params[:domain_id]
  id = params[:application_id]

  name = params[:name]
  # :cartridge param is deprecated because it isn't consistent with
  # the rest of the apis which take :name. Leave it here because
  # some tools may still use it
  name = params[:cartridge] unless name
  colocate_with = params[:colocate_with]

  domain = Domain.get(@cloud_user, domain_id)
  return render_error(:not_found, "Domain #{domain_id} not found", 127,
                      "EMBED_CARTRIDGE") if !domain || !domain.hasAccess?(@cloud_user)

  @domain_name = domain.namespace
  application = get_application(id)
  return render_error(:not_found, "Application '#{id}' not found for domain '#{domain_id}'",
                      101, "EMBED_CARTRIDGE") unless application

  @application_name = application.name
  @application_uuid = application.uuid
  begin
    #container = OpenShift::ApplicationContainerProxy.find_available(application.server_identity)
    container = OpenShift::ApplicationContainerProxy.find_available(nil)
    if not check_cartridge_type(name, container, "embedded")
      carts = get_cached("cart_list_embedded", :expires_in => 21600.seconds) {
                         Application.get_available_cartridges("embedded")}
      return render_error(:bad_request, "Invalid cartridge. Valid values are (#{carts.join(', ')})",
                          109, "EMBED_CARTRIDGE", "cartridge")
    end
  rescue Exception => e
    return render_exception(e, "EMBED_CARTRIDGE")
  end
  
  #TODO: Need a proper method to let us know if cart will get its own gear
  if application.scalable && colocate_with.nil? && (@cloud_user.consumed_gears >= @cloud_user.max_gears) && name != 'jenkins-client-1.4'
    return render_error(:unprocessable_entity, "#{@cloud_user.} has already reached the gear limit of #{@cloud_user.max_gears}",
                        104, "EMBED_CARTRIDGE")
  end

  cart_create_reply = ""
  begin
    application.add_group_override(name, colocate_with) if colocate_with
    cart_create_reply = application.add_dependency(name)
  rescue Exception => e
    return render_exception(e, "EMBED_CARTRIDGE")
  end

  application = get_application(id)

  application.embedded.each do |key, value|
    if key == name
      if $requested_api_version == 1.0
        cartridge = RestCartridge10.new("embedded", key, application, get_url, nil, nolinks)
      else
        cartridge = RestCartridge11.new("embedded", key, application, get_url, nil, nolinks)
      end
      messages = []
      log_msg = "Added #{name} to application #{id}"
      messages.push(Message.new(:info, log_msg))
      messages.push(Message.new(:info, cart_create_reply.resultIO.string, 0, :result))
      messages.push(Message.new(:info, cart_create_reply.appInfoIO.string, 0, :appinfo))
      return render_success(:created, "cartridge", cartridge, "EMBED_CARTRIDGE", log_msg, nil, nil, messages)

    end
  end if application.embedded
  render_error(:internal_server_error, "Cartridge #{name} not embedded within application #{id}", nil, "EMBED_CARTRIDGE")
end

#destroyObject



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
# File 'app/controllers/emb_cart_controller.rb', line 154

def destroy
  domain_id = params[:domain_id]
  id = params[:application_id]
  cartridge = params[:id]

  domain = Domain.get(@cloud_user, domain_id)
  return render_format_error(:not_found, "Domain #{domain_id} not found", 127,
                             "REMOVE_CARTRIDGE") if !domain || !domain.hasAccess?(@cloud_user)

  @domain_name = domain.namespace
  application = get_application(id)
  return render_format_error(:not_found, "Application '#{id}' not found for domain '#{domain_id}'",
                             101, "REMOVE_CARTRIDGE") unless application
  
  @application_name = application.name
  @application_uuid = application.uuid
  return render_format_error(:bad_request, "Cartridge #{cartridge} not embedded within application #{id}",
                             129, "REMOVE_CARTRIDGE") if !application.embedded or !application.embedded.has_key?(cartridge)

  begin
    Rails.logger.debug "Removing #{cartridge} from application #{id}"
    application.remove_dependency(cartridge)
  rescue Exception => e
    return render_format_exception(e, "REMOVE_CARTRIDGE")
  end
    
  application = get_application(id)
  if $requested_api_version == 1.0
    app = RestApplication10.new(application, get_url, nolinks)
  else
    app = RestApplication12.new(application, get_url, nolinks)
  end
  render_format_success(:ok, "application", app, "REMOVE_CARTRIDGE", "Removed #{cartridge} from application #{id}", true)
end

#indexObject

GET /domains//applications//cartridges



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'app/controllers/emb_cart_controller.rb', line 8

def index
  domain_id = params[:domain_id]
  id = params[:application_id]

  domain = Domain.get(@cloud_user, domain_id)
  return render_error(:not_found, "Domain #{domain_id} not found", 127,
                      "LIST_APP_CARTRIDGES") if !domain || !domain.hasAccess?(@cloud_user)

  @domain_name = domain.namespace

  Rails.logger.debug "Getting cartridges for application #{id} under domain #{domain_id}"
  application = get_application(id)
  return render_error(:not_found, "Application '#{id}' not found for domain '#{domain_id}'",
                      101, "LIST_APP_CARTRIDGES") unless application
  #used for user action log
  @application_name = application.name
  @application_uuid = application.uuid
  
  cartridges = get_cartridges(application)

  render_success(:ok, "cartridges", cartridges, "LIST_APP_CARTRIDGES",
                 "Listing cartridges for application #{id} under domain #{domain_id}")
end

#showObject



33
34
35
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
74
75
76
77
78
79
80
# File 'app/controllers/emb_cart_controller.rb', line 33

def show
  domain_id = params[:domain_id]
  application_id = params[:application_id]
  id = params[:id]
  #include=status_messages
  status_messages = (params[:include] == "status_messages")
  
  domain = Domain.get(@cloud_user, domain_id)
  return render_error(:not_found, "Domain #{domain_id} not found", 127,
                      "SHOW_APP_CARTRIDGE") if !domain || !domain.hasAccess?(@cloud_user)
  #used for user action log
  @domain_name = domain.namespace
  Rails.logger.debug "Getting cartridge #{id} for application #{application_id} under domain #{domain_id}"
  application = get_application(application_id)
  return render_error(:not_found, "Application '#{application_id}' not found for domain '#{domain_id}'",
                      101, "SHOW_APP_CARTRIDGE") if !application
 
  @application_name = application.name
  @application_uuid = application.uuid
  cartridge = nil 
  application.embedded.each do |key, value|
    if key == id
      app_status = application.status(key, false) if status_messages
      if $requested_api_version == 1.0
        cartridge = RestCartridge10.new("embedded", key, application, get_url, app_status, nolinks)
      else
        cartridge = RestCartridge11.new("embedded", key, application, get_url, app_status, nolinks)
      end
      break
    end
  end if application.embedded

  if !cartridge and id == application.framework and $requested_api_version != 1.0
    app_status = application.status(application.framework, false) if status_messages
    app_status.each do |gear_status|
      #FIXME: work around until cartridge status hook provides better interface
      message = "#{application.framework} is started."
      message = "#{application.framework} is stopped or inaccessible." if gear_status['message'].match(/(stopped)|(inaccessible)/)
      gear_status['message'] = message
    end if app_status
    cartridge = RestCartridge11.new("standalone", application.framework, application, get_url, app_status, nolinks)
  end
  return render_success(:ok, "cartridge", cartridge, "SHOW_APP_CARTRIDGE",
         "Showing cartridge #{id} for application #{application_id} under domain #{domain_id}") if cartridge

  render_error(:not_found, "Cartridge #{id} not found for application #{application_id}",
               129, "SHOW_APP_CARTRIDGE")
end

#updateObject



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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
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
# File 'app/controllers/emb_cart_controller.rb', line 190

def update
  domain_id = params[:domain_id]
  app_id = params[:application_id]
  cartridge_name = params[:id]
  additional_storage = params[:additional_gear_storage]
  scales_from = params[:scales_from]
  scales_to = params[:scales_to]
  
  domain = Domain.get(@cloud_user, domain_id)
  return render_format_error(:not_found, "Domain #{domain_id} not found", 127,
                      "UPDATE_CARTRIDGE") if !domain || !domain.hasAccess?(@cloud_user)

  @domain_name = domain.namespace
  application = get_application(app_id)
  return render_format_error(:not_found, "Application '#{app_id}' not found for domain '#{domain_id}'",
                      101, "UPDATE_CARTRIDGE") unless application
  #used for user action log
  @application_name = application.name
  @application_uuid = application.uuid
  return render_format_error(:bad_request, "Cartridge #{cartridge_name} for application #{app_id} not found",
                             129, "UPDATE_CARTRIDGE") if ((!application.embedded or !application.embedded.has_key?(cartridge_name)) and application.framework!=cartridge_name)              
  
  storage_map = {}
  application.comp_instance_map.values.each do |cinst|
    if cinst.parent_cart_name==cartridge_name
      group_name = cinst.group_instance_name
      storage_map[group_name] = [] unless storage_map.has_key?(group_name)
      storage_map[group_name] << cinst
    end
  end
  return render_format_error(:not_found, "Cartridge '#{cartridge_name}' for application '#{app_id}' not found",
                      129, "UPDATE_CARTRIDGE") unless storage_map.keys.length>0
              
  #only update attributes that are specified                  
  if additional_storage and additional_storage!=0
    max_storage = @cloud_user.capabilities['max_storage_per_gear']
    return render_format_error(:forbidden, "User is not allowed to change storage quota", 164,
                               "UPDATE_CARTRIDGE") unless max_storage
    num_storage = nil
    begin 
      num_storage = Integer(additional_storage)
    rescue => e
      return render_format_error(:unprocessable_entity, "Invalid storage value provided.", 165, "UPDATE_CARTRIDGE", "additional_gear_storage")
    end
    begin
      # first check against max_storage limit
      storage_map.each do |group_name, component_instance_list|
        ginst = application.group_instance_map[group_name]
        current_sum = 0
        component_instance_list.each { |cinst| current_sum += cinst.addtl_fs_gb }
        current_sum = ginst.addtl_fs_gb-current_sum
        current_sum += ginst.get_cached_min_storage_in_gb
        current_sum += num_storage
        return render_format_error(:forbidden, "Total additional storage for all cartridges on gear should be less than max_storage_per_gear (new_storage: #{current_sum}, max: #{max_storage}).", 166, "UPDATE_CARTRIDGE", "additional_gear_storage") if current_sum>max_storage
      end
      # now actually change the quota
      storage_map.each do |group_name, component_instance_list|
        each_component_share = (Float(num_storage))/component_instance_list.length
        ginst = application.group_instance_map[group_name]
        component_instance_list.each { |cinst| cinst.set_additional_quota(application, each_component_share) }
      end
      application.save
    rescue Exception => e
      return render_format_exception(e, "UPDATE_CARTRIDGE")
    end             
  end

  if scales_from or scales_to
    begin
      application.set_user_min_max(storage_map, scales_from, scales_to)
    rescue OpenShift::UserException=>e
      return render_format_error(:unprocessable_entity, e.message, 168,
                       "UPDATE_CARTRIDGE") 
    rescue Exception=>e
      return render_format_error(:forbidden, e.message, 164,
                       "UPDATE_CARTRIDGE") 
    end
  end
  cart_type = cartridge_name==application.framework ? "standalone" : "embedded"
  if $requested_api_version == 1.0
    cartridge = RestCartridge10.new(cart_type, cartridge_name, application, get_url, nil, nolinks)
  else
    cartridge = RestCartridge11.new(cart_type, cartridge_name, application, get_url, nil, nolinks)
  end
  render_format_success(:ok, "cartridge", cartridge, "UPDATE_CARTRIDGE", "Updated #{cartridge_name} from application #{app_id}", true)
end