5 // Created by Mike Mayo on 10/21/10.
6 // The OpenStack project is provided under the Apache 2.0 license.
9 #import "AccountManager.h"
10 #import "OpenStackAccount.h"
11 #import "OpenStackRequest.h"
17 #import "StorageObject.h"
18 #import "GetServersRequest.h"
19 #import "GetContainersRequest.h"
20 #import "GetObjectsRequest.h"
21 #import "GetImagesRequest.h"
22 #import "ASINetworkQueue.h"
23 #import "UpdateCDNContainerRequest.h"
24 #import "GetFlavorsRequest.h"
25 #import "LoadBalancer.h"
26 #import "LoadBalancerRequest.h"
27 #import "APICallback.h"
34 @implementation AccountManager
36 @synthesize account, queue;
38 #pragma mark - Callbacks
40 - (APICallback *)callbackWithRequest:(id)request success:(APIResponseBlock)success failure:(APIResponseBlock)failure {
41 APICallback *callback = [[[APICallback alloc] initWithAccount:self.account request:request] autorelease];
42 ((OpenStackRequest *)request).delegate = self;
43 ((OpenStackRequest *)request).callback = callback;
45 [request setCompletionBlock:^{
46 if ([request isSuccess]) {
54 [request setFailedBlock:^{
58 [request startAsynchronous];
62 - (APICallback *)callbackWithRequest:(id)request success:(APIResponseBlock)success {
63 return [self callbackWithRequest:request success:success failure:^(OpenStackRequest *request){}];
66 - (APICallback *)callbackWithRequest:(id)request {
67 return [self callbackWithRequest:request success:^(OpenStackRequest *request){} failure:^(OpenStackRequest *request){}];
70 #pragma mark - Notification
72 - (NSString *)notificationName:(NSString *)key identifier:(NSString *)identifier {
73 return [NSString stringWithFormat:@"%@-%@-%i", key, self.account.uuid, identifier];
76 - (void)requestFinished:(OpenStackRequest *)request {
77 NSString *notificationName = [request.userInfo objectForKey:@"notificationName"];
78 id notificationObject = [request.userInfo objectForKey:@"notificationObject"];
80 if ([request isSuccess]) {
81 NSNotification *notification = [NSNotification notificationWithName:[NSString stringWithFormat:@"%@Succeeded", notificationName] object:notificationObject];
82 [[NSNotificationCenter defaultCenter] postNotification:notification];
84 NSNotification *notification = [NSNotification notificationWithName:[NSString stringWithFormat:@"%@Failed", notificationName] object:notificationObject userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
85 [[NSNotificationCenter defaultCenter] postNotification:notification];
89 - (void)requestFailed:(OpenStackRequest *)request {
90 NSString *notificationName = [request.userInfo objectForKey:@"notificationName"];
91 id notificationObject = [request.userInfo objectForKey:@"notificationObject"];
92 NSNotification *notification = [NSNotification notificationWithName:[NSString stringWithFormat:@"%@Failed", notificationName] object:notificationObject userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
93 [[NSNotificationCenter defaultCenter] postNotification:notification];
96 - (void)sendRequest:(OpenStackRequest *)request name:(NSString *)name object:(id)notificationObject {
97 request.delegate = self;
98 request.userInfo = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:name, notificationObject, nil] forKeys:[NSArray arrayWithObjects:@"notificationName", @"notificationObject", nil]];
99 [request startAsynchronous];
102 - (void)notify:(NSString *)name request:(OpenStackRequest *)request {
103 NSNotification *notification = [NSNotification notificationWithName:name object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
104 [[NSNotificationCenter defaultCenter] postNotification:notification];
107 - (void)notify:(NSString *)name request:(OpenStackRequest *)request object:(id)object {
108 NSNotification *notification = [NSNotification notificationWithName:name object:object userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
109 [[NSNotificationCenter defaultCenter] postNotification:notification];
112 #pragma mark - API Calls
114 #pragma mark Get Limits
117 __block OpenStackRequest *request = [OpenStackRequest getLimitsRequest:self.account];
118 request.delegate = self;
119 [request setCompletionBlock:^{
120 if ([request isSuccess] && [request limits]) {
121 self.account.rateLimits = [request rateLimits];
122 [self.account persist];
123 [self notify:@"getLimitsSucceeded" request:request object:self.account];
125 [self notify:@"getLimitsFailed" request:request object:self.account];
128 [request setFailedBlock:^{
129 [self notify:@"getLimitsFailed" request:request object:self.account];
131 [request startAsynchronous];
134 #pragma mark Reboot Server
136 - (void)softRebootServer:(Server *)server {
137 TrackEvent(CATEGORY_SERVER, EVENT_REBOOTED);
139 __block OpenStackRequest *request = [OpenStackRequest softRebootServerRequest:self.account server:server];
140 request.delegate = self;
141 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
142 [request setCompletionBlock:^{
143 [self notify:([request isSuccess] ? @"rebootSucceeded" : @"rebootFailed") request:request object:[request.userInfo objectForKey:@"server"]];
145 [request setFailedBlock:^{
146 [self notify:@"rebootFailed" request:request object:[request.userInfo objectForKey:@"server"]];
148 [request startAsynchronous];
151 - (void)hardRebootServer:(Server *)server {
152 TrackEvent(CATEGORY_SERVER, EVENT_REBOOTED);
154 __block OpenStackRequest *request = [OpenStackRequest hardRebootServerRequest:self.account server:server];
155 request.delegate = self;
156 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
157 [request setCompletionBlock:^{
158 [self notify:([request isSuccess] ? @"rebootSucceeded" : @"rebootFailed") request:request object:[request.userInfo objectForKey:@"server"]];
160 [request setFailedBlock:^{
161 [self notify:@"rebootFailed" request:request object:[request.userInfo objectForKey:@"server"]];
163 [request startAsynchronous];
166 #pragma mark Change Admin Password
168 - (void)changeAdminPassword:(Server *)server password:(NSString *)password {
169 TrackEvent(CATEGORY_SERVER, EVENT_PASSWORD_CHANGED);
171 __block OpenStackRequest *request = [OpenStackRequest changeServerAdminPasswordRequest:self.account server:server password:password];
172 request.delegate = self;
173 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
174 [request setCompletionBlock:^{
175 [self notify:([request isSuccess] ? @"changeAdminPasswordSucceeded" : @"changeAdminPasswordFailed") request:request object:[request.userInfo objectForKey:@"server"]];
177 [request setFailedBlock:^{
178 [self notify:@"changeAdminPasswordFailed" request:request object:[request.userInfo objectForKey:@"server"]];
180 [request startAsynchronous];
183 #pragma mark Rename Server
185 - (APICallback *)renameServer:(Server *)server name:(NSString *)name {
186 TrackEvent(CATEGORY_SERVER, EVENT_RENAMED);
188 __block OpenStackRequest *request = [OpenStackRequest renameServerRequest:self.account server:server name:name];
189 return [self callbackWithRequest:request];
192 #pragma mark Delete Server
194 - (void)deleteServer:(Server *)server {
195 TrackEvent(CATEGORY_SERVER, EVENT_DELETED);
197 __block OpenStackRequest *request = [OpenStackRequest deleteServerRequest:self.account server:server];
198 request.delegate = self;
199 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
200 [request setCompletionBlock:^{
201 [self notify:([request isSuccess] ? @"deleteServerSucceeded" : @"deleteServerFailed") request:request object:[request.userInfo objectForKey:@"server"]];
202 [self notify:([request isSuccess] ? @"deleteServerSucceeded" : @"deleteServerFailed") request:request object:self.account];
204 [request setFailedBlock:^{
205 [self notify:@"deleteServerFailed" request:request object:[request.userInfo objectForKey:@"server"]];
208 [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
210 [queue addOperation:request];
213 #pragma mark Create Server
215 - (void)createServer:(Server *)server {
216 TrackEvent(CATEGORY_SERVER, EVENT_CREATED);
218 __block OpenStackRequest *request = [OpenStackRequest createServerRequest:self.account server:server];
219 request.delegate = self;
220 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
222 // TODO: make these success block and failure block with "response" arg
223 [request setCompletionBlock:^{
224 NSLog(@"create server response: %i - %@", request.responseStatusCode, request.responseStatusMessage);
225 NSLog(@"body: %@", [request responseString]);
226 [self notify:([request isSuccess] ? @"createServerSucceeded" : @"createServerFailed") request:request object:[request.userInfo objectForKey:@"server"]];
227 [self notify:([request isSuccess] ? @"createServerSucceeded" : @"createServerFailed") request:request object:self.account];
229 [request setFailedBlock:^{
230 NSLog(@"create server response: %i - %@", request.responseStatusCode, request.responseStatusMessage);
231 NSLog(@"body: %@", [request responseString]);
232 [self notify:@"createServerFailed" request:request object:[request.userInfo objectForKey:@"server"]];
235 [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
237 [queue addOperation:request];
240 #pragma mark Resize Server
242 - (void)resizeServer:(Server *)server flavor:(Flavor *)flavor {
243 TrackEvent(CATEGORY_SERVER, EVENT_RESIZED);
245 __block OpenStackRequest *request = [OpenStackRequest resizeServerRequest:self.account server:server flavor:flavor];
246 request.delegate = self;
247 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
248 [request setCompletionBlock:^{
249 NSString *name = [request isSuccess] ? @"resizeServerSucceeded" : @"resizeServerFailed";
250 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:name identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
251 [[NSNotificationCenter defaultCenter] postNotification:notification];
253 [request setFailedBlock:^{
254 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:@"resizeServerFailed" identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
255 [[NSNotificationCenter defaultCenter] postNotification:notification];
257 [request startAsynchronous];
260 - (void)confirmResizeServer:(Server *)server {
261 __block OpenStackRequest *request = [OpenStackRequest confirmResizeServerRequest:self.account server:server];
262 request.delegate = self;
263 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
264 [request setCompletionBlock:^{
265 NSString *name = [request isSuccess] ? @"confirmResizeServerSucceeded" : @"confirmResizeServerFailed";
266 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:name identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
267 [[NSNotificationCenter defaultCenter] postNotification:notification];
269 [request setFailedBlock:^{
270 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:@"confirmResizeServerFailed" identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
271 [[NSNotificationCenter defaultCenter] postNotification:notification];
274 [request startAsynchronous];
277 - (void)revertResizeServer:(Server *)server {
278 __block OpenStackRequest *request = [OpenStackRequest revertResizeServerRequest:self.account server:server];
279 request.delegate = self;
280 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
281 [request setCompletionBlock:^{
282 NSString *name = [request isSuccess] ? @"revertResizeServerSucceeded" : @"revertResizeServerFailed";
283 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:name identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
284 [[NSNotificationCenter defaultCenter] postNotification:notification];
286 [request setFailedBlock:^{
287 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:@"revertResizeServerFailed" identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
288 [[NSNotificationCenter defaultCenter] postNotification:notification];
290 [request startAsynchronous];
293 - (void)rebuildServer:(Server *)server image:(Image *)image {
294 TrackEvent(CATEGORY_SERVER, EVENT_REBUILT);
296 __block OpenStackRequest *request = [OpenStackRequest rebuildServerRequest:self.account server:server image:image];
297 request.delegate = self;
298 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
299 [request setCompletionBlock:^{
300 NSString *name = [request isSuccess] ? @"rebuildServerSucceeded" : @"rebuildServerFailed";
301 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:name identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
302 [[NSNotificationCenter defaultCenter] postNotification:notification];
304 [request setFailedBlock:^{
305 NSNotification *notification = [NSNotification notificationWithName:[self notificationName:@"rebuildServerFailed" identifier:server.identifier] object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
306 [[NSNotificationCenter defaultCenter] postNotification:notification];
308 [request startAsynchronous];
311 - (void)getBackupSchedule:(Server *)server {
312 __block OpenStackRequest *request = [OpenStackRequest getBackupScheduleRequest:self.account server:server];
313 request.delegate = self;
314 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
315 [request setCompletionBlock:^{
316 server.backupSchedule = [request backupSchedule];
317 [self notify:([request isSuccess] ? @"getBackupScheduleSucceeded" : @"getBackupScheduleFailed") request:request object:[request.userInfo objectForKey:@"server"]];
319 [request setFailedBlock:^{
320 [self notify:@"getBackupScheduleFailed" request:request object:[request.userInfo objectForKey:@"server"]];
322 [request startAsynchronous];
325 - (void)updateBackupSchedule:(Server *)server {
326 TrackEvent(CATEGORY_SERVER, EVENT_BACKUP_SCHEDULE_CHANGED);
328 __block OpenStackRequest *request = [OpenStackRequest updateBackupScheduleRequest:self.account server:server];
329 request.delegate = self;
330 request.userInfo = [NSDictionary dictionaryWithObject:server forKey:@"server"];
331 [request setCompletionBlock:^{
332 [self notify:([request isSuccess] ? @"updateBackupScheduleSucceeded" : @"updateBackupScheduleFailed") request:request object:[request.userInfo objectForKey:@"server"]];
333 [self notify:([request isSuccess] ? @"updateBackupScheduleSucceeded" : @"updateBackupScheduleFailed") request:request object:self.account];
335 [request setFailedBlock:^{
336 [self notify:@"updateBackupScheduleFailed" request:request object:[request.userInfo objectForKey:@"server"]];
337 [self notify:@"updateBackupScheduleFailed" request:request object:self.account];
339 [request startAsynchronous];
342 #pragma mark Get Image
344 - (void)getImage:(Server *)server {
345 __block OpenStackRequest *request = [OpenStackRequest getImageRequest:self.account imageId:server.imageId];
346 request.delegate = self;
347 request.userInfo = [NSDictionary dictionaryWithObject:server.imageId forKey:@"imageId"];
348 [request setCompletionBlock:^{
349 if ([request isSuccess]) {
350 Image *image = [request image];
351 if ([image isKindOfClass:[Image class]]) {
352 image.canBeLaunched = NO;
353 [self.account.images setObject:image forKey:image.identifier];
354 [self.account persist];
356 [self notify:@"getImageSucceeded" request:request];
358 [self notify:@"getImageFailed" request:request object:[request.userInfo objectForKey:@"imageId"]];
361 [request setFailedBlock:^{
362 [self notify:@"getImageFailed" request:request object:[request.userInfo objectForKey:@"imageId"]];
364 [request startAsynchronous];
367 #pragma mark Get Servers
371 [self setQueue:[[[ASINetworkQueue alloc] init] autorelease]];
373 GetServersRequest *request = [GetServersRequest request:self.account];
374 [queue addOperation:request];
377 - (APICallback *)getServersWithCallback {
378 __block OpenStackRequest *request = [OpenStackRequest serversRequest:self.account method:@"GET" path:@"/servers/detail"];
379 return [self callbackWithRequest:request];
383 #pragma mark Get Flavors
387 [self setQueue:[[[ASINetworkQueue alloc] init] autorelease]];
389 GetFlavorsRequest *request = [GetFlavorsRequest request:self.account];
390 [queue addOperation:request];
393 #pragma mark Get Images
397 [self setQueue:[[[ASINetworkQueue alloc] init] autorelease]];
399 GetImagesRequest *request = [GetImagesRequest request:self.account];
400 [queue addOperation:request];
404 #pragma mark Object Storage
407 - (APICallback *)getStorageAccountInfo {
408 __block OpenStackRequest *request = [OpenStackRequest getStorageAccountInfoRequest:self.account];
409 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
410 self.account.containerCount = [[[request responseHeaders] objectForKey:@"X-Account-Container-Count"] intValue];
411 NSString *numStr = [[request responseHeaders] objectForKey:@"X-Account-Bytes-Used"];
412 self.account.totalBytesUsed = strtoull([numStr UTF8String], NULL, 0);
413 [self.account persist];
414 self.account.containerCount = [self.account.containers count];
418 - (APICallback *)getSharingAccounts {
419 __block OpenStackRequest *request = [OpenStackRequest getSharingAccountsRequest:self.account];
420 return [self callbackWithRequest:request];
423 - (APICallback *)getContainers {
424 __block OpenStackRequest *request = [OpenStackRequest filesRequest:self.account method:@"GET" path:@""];
425 return [self callbackWithRequest:request];
428 - (APICallback *)createContainer:(Container *)container {
429 TrackEvent(CATEGORY_CONTAINERS, EVENT_CREATED);
431 __block OpenStackRequest *request = [OpenStackRequest createContainerRequest:self.account container:container];
432 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
434 [self.account.containers setObject:container forKey:container.name];
435 [self.account persist];
436 self.account.containerCount = [self.account.containers count];
440 - (APICallback *)deleteContainer:(Container *)container {
441 TrackEvent(CATEGORY_CONTAINERS, EVENT_DELETED);
442 __block OpenStackRequest *request = [OpenStackRequest deleteContainerRequest:self.account container:container];
443 return [self callbackWithRequest:request];
447 - (void)getObjects:(Container *)container {
448 [self getObjects:container afterMarker:nil objectsBuffer:nil];
451 - (void)getObjects:(Container *)container
452 afterMarker:(NSString *)marker
453 objectsBuffer:(NSMutableDictionary *)objectsBuffer {
455 [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
457 GetObjectsRequest *request = [GetObjectsRequest request:self.account container:container marker:marker objectsBuffer:objectsBuffer];
458 [queue addOperation:request];
461 - (void)updateCDNContainer:(Container *)container {
462 TrackEvent(CATEGORY_CONTAINERS, EVENT_UPDATED);
465 [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
467 UpdateCDNContainerRequest *request = [UpdateCDNContainerRequest request:self.account container:container];
468 [queue addOperation:request];
471 - (void)getObjectsSucceeded:(OpenStackRequest *)request {
472 if ([request isSuccess]) {
473 Container *container = [request.userInfo objectForKey:@"container"];
474 NSMutableDictionary *objects = [request objects];
475 container.rootFolder = [Folder folder];
476 container.rootFolder.objects = objects;
477 [self.account persist];
479 NSNotification *notification = [NSNotification notificationWithName:@"getObjectsSucceeded" object:self.account userInfo:[NSDictionary dictionaryWithObject:container forKey:@"container"]];
480 [[NSNotificationCenter defaultCenter] postNotification:notification];
482 NSNotification *notification = [NSNotification notificationWithName:@"getObjectsFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
483 [[NSNotificationCenter defaultCenter] postNotification:notification];
487 - (void)getObjectsFailed:(OpenStackRequest *)request {
488 NSNotification *notification = [NSNotification notificationWithName:@"getObjectsFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
489 [[NSNotificationCenter defaultCenter] postNotification:notification];
492 - (APICallback *)getObjectInfo:(Container *)container object:(StorageObject *)object {
493 __block OpenStackRequest *request = [OpenStackRequest getObjectInfoRequest:self.account container:container object:object];
494 return [self callbackWithRequest:request];
497 - (APICallback *)getObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate {
498 __block OpenStackRequest *request = [OpenStackRequest getObjectRequest:self.account container:container object:object];
499 request.delegate = self;
500 request.downloadProgressDelegate = downloadProgressDelegate;
501 request.showAccurateProgress = YES;
502 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
504 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
505 NSString *documentsDirectory = [paths objectAtIndex:0];
506 NSString *shortPath = [NSString stringWithFormat:@"/%@/%@", container.name, object.fullPath];
507 NSString *filePath = [documentsDirectory stringByAppendingString:shortPath];
508 NSString *directoryPath = [filePath stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"/%@", object.name] withString:@""];
510 NSFileManager *fileManager = [NSFileManager defaultManager];
511 if ([fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:nil]) {
513 [[request responseData] writeToFile:filePath atomically:YES];
520 - (APICallback *)writeObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate {
521 TrackEvent(CATEGORY_FILES, EVENT_CREATED);
523 __block OpenStackRequest *request = [OpenStackRequest writeObjectRequest:self.account container:container object:object];
524 request.delegate = self;
525 request.uploadProgressDelegate = downloadProgressDelegate;
526 request.showAccurateProgress = YES;
528 return [self callbackWithRequest:request];
531 - (APICallback *)deleteObject:(Container *)container object:(StorageObject *)object {
532 TrackEvent(CATEGORY_FILES, EVENT_DELETED);
534 __block OpenStackRequest *request = [OpenStackRequest deleteObjectRequest:self.account container:container object:object];
535 return [self callbackWithRequest:request];
538 - (APICallback *)writeObjectMetadata:(Container *)container object:(StorageObject *)object {
539 __block OpenStackRequest *request = [OpenStackRequest writeObjectMetadataRequest:self.account container:container object:object];
540 return [self callbackWithRequest:request];
543 - (APICallback *)writeAccountMetadata:(NSDictionary *)accountInfo {
544 __block OpenStackRequest *request = [OpenStackRequest writeAccountMetadataRequest:self.account withAccountInfo:accountInfo];
545 return [self callbackWithRequest:request];
548 - (APICallback *)writeContainerPolicy:(Container *)container {
549 __block OpenStackRequest *request = [OpenStackRequest writeContainerPolicyRequest:self.account container:container];
550 return [self callbackWithRequest:request];
554 #pragma mark Load Balancing
556 - (APICallback *)getLoadBalancers:(NSString *)endpoint {
557 __block LoadBalancerRequest *request = [LoadBalancerRequest getLoadBalancersRequest:self.account endpoint:endpoint];
558 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
559 if (!self.account.loadBalancers) {
560 self.account.loadBalancers = [[[NSMutableDictionary alloc] initWithCapacity:2] autorelease];
563 NSLog(@"%@", self.account.loadBalancers);
564 NSLog(@"%@", [(LoadBalancerRequest *)request loadBalancers:self.account]);
565 NSLog(@"%@", endpoint);
566 NSMutableDictionary *lbs = [(LoadBalancerRequest *)request loadBalancers:self.account];
568 for (NSString *identifier in lbs) {
569 LoadBalancer *lb = [lbs objectForKey:identifier];
570 lb.region = [self.account loadBalancerRegionForEndpoint:endpoint];
571 NSLog(@"lb.region = %@", lb.region);
574 [self.account.loadBalancers setObject:lbs forKey:endpoint];
575 [self.account persist];
579 - (APICallback *)getLoadBalancerDetails:(LoadBalancer *)loadBalancer endpoint:(NSString *)endpoint {
580 __block LoadBalancerRequest *request = [LoadBalancerRequest getLoadBalancerDetailsRequest:self.account loadBalancer:loadBalancer endpoint:endpoint];
581 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
583 LoadBalancer *newLB = [(LoadBalancerRequest *)request loadBalancer:self.account];
584 loadBalancer.status = newLB.status;
585 loadBalancer.nodes = newLB.nodes;
586 loadBalancer.connectionLoggingEnabled = newLB.connectionLoggingEnabled;
588 // if (!self.account.loadBalancers) {
589 // self.account.loadBalancers = [[NSMutableDictionary alloc] initWithCapacity:2];
592 // NSLog(@"%@", self.account.loadBalancers);
593 // NSLog(@"%@", [(LoadBalancerRequest *)request loadBalancers]);
594 // NSLog(@"%@", endpoint);
595 // NSMutableDictionary *lbs = [(LoadBalancerRequest *)request loadBalancers];
597 // for (NSString *identifier in lbs) {
598 // LoadBalancer *lb = [lbs objectForKey:identifier];
599 // lb.region = [self.account loadBalancerRegionForEndpoint:endpoint];
600 // NSLog(@"lb.region = %@", lb.region);
603 // [self.account.loadBalancers setObject:lbs forKey:endpoint];
604 [self.account persist];
608 - (APICallback *)getLoadBalancerProtocols:(NSString *)endpoint {
609 __block LoadBalancerRequest *request = [LoadBalancerRequest getLoadBalancerProtocols:self.account endpoint:endpoint];
610 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
611 self.account.lbProtocols = [(LoadBalancerRequest *)request protocols];
615 - (APICallback *)createLoadBalancer:(LoadBalancer *)loadBalancer {
616 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_CREATED);
618 NSString *endpoint = @"";
620 for (NSString *url in [self.account loadBalancerURLs]) {
621 if ([url hasPrefix:[NSString stringWithFormat:@"https://%@", [loadBalancer.region lowercaseString]]]) {
627 __block LoadBalancerRequest *request = [LoadBalancerRequest createLoadBalancerRequest:self.account loadBalancer:loadBalancer endpoint:endpoint];
628 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
632 - (APICallback *)updateLoadBalancer:(LoadBalancer *)loadBalancer {
633 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_UPDATED);
634 NSString *endpoint = [self.account loadBalancerEndpointForRegion:loadBalancer.region];
635 __block LoadBalancerRequest *request = [LoadBalancerRequest updateLoadBalancerRequest:self.account loadBalancer:loadBalancer endpoint:endpoint];
636 return [self callbackWithRequest:request];
639 - (APICallback *)deleteLoadBalancer:(LoadBalancer *)loadBalancer {
640 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_DELETED);
641 NSString *endpoint = [self.account loadBalancerEndpointForRegion:loadBalancer.region];
642 NSLog(@"endpoint: %@", endpoint);
643 __block LoadBalancerRequest *request = [LoadBalancerRequest deleteLoadBalancerRequest:self.account loadBalancer:loadBalancer endpoint:endpoint];
644 return [self callbackWithRequest:request];
647 - (APICallback *)updateLoadBalancerConnectionLogging:(LoadBalancer *)loadBalancer {
648 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_UPDATED_LB_CONNECTION_LOGGING);
649 __block LoadBalancerRequest *request = [LoadBalancerRequest updateConnectionLoggingRequest:self.account loadBalancer:loadBalancer];
650 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
651 } failure:^(OpenStackRequest *request) {
652 loadBalancer.connectionLoggingEnabled = !loadBalancer.connectionLoggingEnabled;
656 - (APICallback *)getLoadBalancerConnectionThrottling:(LoadBalancer *)loadBalancer {
657 __block LoadBalancerRequest *request = [LoadBalancerRequest getConnectionThrottlingRequest:self.account loadBalancer:loadBalancer];
658 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
659 loadBalancer.connectionThrottle = [(LoadBalancerRequest *)request connectionThrottle];
663 - (APICallback *)updateLoadBalancerConnectionThrottling:(LoadBalancer *)loadBalancer {
664 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_UPDATED_LB_CONNECTION_THROTTLING);
665 __block LoadBalancerRequest *request = [LoadBalancerRequest updateConnectionThrottlingRequest:self.account loadBalancer:loadBalancer];
666 return [self callbackWithRequest:request];
669 - (APICallback *)deleteLoadBalancerConnectionThrottling:(LoadBalancer *)loadBalancer {
670 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_DISABLED_LB_CONNECTION_THROTTLING);
671 __block LoadBalancerRequest *request = [LoadBalancerRequest disableConnectionThrottlingRequest:self.account loadBalancer:loadBalancer];
672 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
673 loadBalancer.connectionThrottle = nil;
677 - (APICallback *)getLoadBalancerUsage:(LoadBalancer *)loadBalancer endpoint:(NSString *)endpoint {
678 __block LoadBalancerRequest *request = [LoadBalancerRequest getLoadBalancerUsageRequest:self.account loadBalancer:loadBalancer endpoint:endpoint];
679 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
680 loadBalancer.usage = [(LoadBalancerRequest *)request usage];
684 - (APICallback *)addLBNodes:(NSArray *)nodes loadBalancer:(LoadBalancer *)loadBalancer endpoint:(NSString *)endpoint {
685 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_ADDED_LB_NODES);
686 __block LoadBalancerRequest *request = [LoadBalancerRequest addLoadBalancerNodesRequest:self.account loadBalancer:loadBalancer nodes:nodes endpoint:endpoint];
687 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
688 for (LoadBalancerNode *node in nodes) {
689 [loadBalancer.nodes addObject:node];
691 [self.account persist];
695 - (APICallback *)updateLBNode:(LoadBalancerNode *)node loadBalancer:(LoadBalancer *)loadBalancer endpoint:(NSString *)endpoint {
696 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_UPDATED_LB_NODE);
697 __block LoadBalancerRequest *request = [LoadBalancerRequest updateLoadBalancerNodeRequest:self.account loadBalancer:loadBalancer node:node endpoint:endpoint];
698 return [self callbackWithRequest:request];
701 - (APICallback *)deleteLBNode:(LoadBalancerNode *)node loadBalancer:(LoadBalancer *)loadBalancer endpoint:(NSString *)endpoint {
702 TrackEvent(CATEGORY_LOAD_BALANCER, EVENT_DELETED_LB_NODE);
703 __block LoadBalancerRequest *request = [LoadBalancerRequest deleteLoadBalancerNodeRequest:self.account loadBalancer:loadBalancer node:node endpoint:endpoint];
704 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
705 [loadBalancer.nodes removeObject:node];
709 - (APICallback *)authenticate {
710 __block OpenStackRequest *request = [OpenStackRequest authenticationRequest:self.account];
711 return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
712 if ([request isSuccess]) {
713 self.account.authToken = [[request responseHeaders] objectForKey:@"X-Auth-Token"];
714 self.account.serversURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Server-Management-Url"]];
716 if (![[request responseHeaders] objectForKey:@"X-Storage-URL"]) {
717 NSString *filesStorageURL = [NSString stringWithFormat:@"%@/v1/%@",
718 [self.account.hostURL absoluteString],
719 [self.account username]];
721 self.account.filesURL = [NSURL URLWithString:filesStorageURL];
724 self.account.filesURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Storage-Url"]];
727 self.account.pithosPublicLinkURLPrefix = self.account.hostURL;
728 self.account.pithosLoginURLPrefix = [NSURL URLWithString:
729 [[self.account.hostURL absoluteString]
730 stringByAppendingString:@"/login"]];
731 self.account.cdnURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Cdn-Management-Url"]];
733 [self.account persist];
740 #pragma mark Memory Management