Fix compile errors
[pithos-ios] / Classes / Server.m
1 //
2 //  Server.m
3 //  OpenStack
4 //
5 //  Created by Mike Mayo on 10/4/10.
6 //  The OpenStack project is provided under the Apache 2.0 license.
7 //
8
9 #import "Server.h"
10 #import "Base64.h"
11 #import "NSObject+SBJSON.h"
12 #import "Flavor.h"
13 #import "Image.h"
14 #import "OpenStackAccount.h"
15 #import "NSObject+NSCoding.h"
16 #import "NSString+Conveniences.h"
17
18
19 @implementation Server
20
21 @synthesize progress, imageId, flavorId, status, hostId, addresses, metadata, image, flavor, urls, personality, backupSchedule, rootPassword;
22
23
24 // TODO: getter/setter for rootPassword should use Keychain class
25 // TODO: generate uuid for servers.  key password on uuid
26
27 #pragma mark -
28 #pragma mark Serialization
29
30 - (void)encodeWithCoder: (NSCoder *)coder {
31     [self autoEncodeWithCoder:coder];
32 }
33
34 - (id)initWithCoder:(NSCoder *)coder {
35     if ((self = [super init])) {
36         [self autoDecode:coder];
37     }
38     
39     return self;
40 }
41
42 - (id)copyWithZone:(NSZone *)zone {
43     Server *copy = [[Server allocWithZone:zone] init];
44     copy.identifier = self.identifier;
45     copy.imageId = self.imageId;
46     copy.flavorId = self.flavorId;
47     copy.status = self.status;
48     copy.addresses = self.addresses;
49     copy.image = self.image;
50     copy.flavor = self.flavor;
51     return copy;
52 }
53
54 #pragma mark - JSON
55
56 - (void)populateWithJSON:(NSDictionary *)dict {
57     self.identifier = [dict objectForKey:@"id"];
58     if ([dict objectForKey:@"flavorId"]) {
59         self.flavorId = [[dict objectForKey:@"flavorId"] description];
60     }
61     if ([dict objectForKey:@"flavor"]) {
62         Flavor *f = [Flavor fromJSON:[dict objectForKey:@"flavor"]];
63         self.flavorId = f.identifier;
64     }
65     if ([dict objectForKey:@"imageId"]) {
66         self.imageId = [[dict objectForKey:@"imageId"] description];
67     }
68     if ([dict objectForKey:@"image"]) {
69         self.image = [Image fromJSON:[dict objectForKey:@"image"]];
70         self.imageId = self.image.identifier;
71     }
72     self.addresses = [dict objectForKey:@"addresses"];
73     
74     if ([[self.addresses objectForKey:@"public"] isKindOfClass:[NSArray class]]) {
75         
76         NSMutableDictionary *newAddresses = [[[NSMutableDictionary alloc] initWithCapacity:2] autorelease];
77         
78         NSArray *publicIPs = [self.addresses objectForKey:@"public"];
79         NSMutableArray *newPublicIPs = [[[NSMutableArray alloc] initWithCapacity:[publicIPs count]] autorelease];
80         for (NSDictionary *ip in publicIPs) {
81             if ([ip isKindOfClass:[NSDictionary class]]) {
82                 [newPublicIPs addObject:[ip objectForKey:@"addr"]];
83             } else {
84                 [newPublicIPs addObject:ip];
85             }
86         }
87         [newAddresses setObject:newPublicIPs forKey:@"public"];
88         
89         NSArray *privateIPs = [self.addresses objectForKey:@"private"];
90         NSMutableArray *newPrivateIPs = [[[NSMutableArray alloc] initWithCapacity:[privateIPs count]] autorelease];
91         for (NSDictionary *ip in privateIPs) {
92             if ([ip isKindOfClass:[NSDictionary class]]) {
93                 [newPrivateIPs addObject:[ip objectForKey:@"addr"]];
94             } else {
95                 [newPrivateIPs addObject:ip];
96             }
97         }
98         [newAddresses setObject:newPrivateIPs forKey:@"private"];
99         
100         self.addresses = newAddresses;
101     }
102     
103     self.status = [dict objectForKey:@"status"];
104     
105     if ([dict objectForKey:@"progress"]) {
106         self.progress = [[dict objectForKey:@"progress"] intValue];
107     }
108 }
109
110 - (id)initWithJSONDict:(NSDictionary *)dict {
111     self = [super initWithJSONDict:dict];
112     if (self) {
113         [self populateWithJSON:dict];        
114     }
115     return self;
116 }
117
118 + (Server *)fromJSON:(NSDictionary *)dict {
119     Server *server = [[[Server alloc] initWithJSONDict:dict] autorelease];
120     [server populateWithJSON:dict];
121     return server;
122 }
123
124 - (NSString *)toJSON:(NSString *)apiVersion {
125     BOOL version1 = [apiVersion isEqualToString:@"1.0"];
126     
127     NSString *json
128         = @"{ \"server\": { "
129         "        \"name\": \"<name>\","
130         "        \"<flavorType>\": <flavor>,"
131         "        \"<imageType>\": <image>"
132         "        <metadata><personality>"
133         "  }}";
134     json = [json replace:@"<name>" with:self.name];    
135     json = [json replace:@"<flavorType>" with:version1 ? @"flavorId" : @"flavorRef"];
136     
137     if (version1) {
138         json = [json replace:@"<flavor>" with:self.flavorId];
139     } else {
140         json = [json replace:@"<flavor>" with:[NSString stringWithFormat:@"\"%@\"", self.flavorId]];
141     }
142     
143     json = [json replace:@"<imageType>" with:version1 ? @"imageId" : @"imageRef"];
144
145     if (version1) {
146         json = [json replace:@"<image>" with:self.imageId];
147     } else {
148         json = [json replace:@"<image>" with:[NSString stringWithFormat:@"\"%@\"", self.imageId]];
149     }
150     
151     if (self.metadata && [self.metadata count] > 0) {
152         json = [json replace:@"<metadata>" with:[NSString stringWithFormat:@", \"metadata\": %@", [self.metadata JSONRepresentation]]];
153     } else {
154         json = [json replace:@"<metadata>" with:@""];
155     }
156
157     if (self.personality && [self.personality count] > 0) {
158         NSString *personalityJSON = @", \"personality\": [ ";
159         
160         NSArray *paths = [self.personality allKeys];
161         for (int i = 0; i < [paths count]; i++) {
162             NSString *path = [paths objectAtIndex:i];
163             personalityJSON = [personalityJSON stringByAppendingString:[NSString stringWithFormat:@"{ \"path\": \"%@\", \"contents\": \"%@\" }", path, [Base64 encode:[[self.personality objectForKey:path] dataUsingEncoding:NSUTF8StringEncoding]]]];
164             if (i < [paths count] - 1) {
165                 personalityJSON = [json stringByAppendingString:@", "];
166             }
167         }
168         personalityJSON = [personalityJSON stringByAppendingString:@" ]"];
169         
170         json = [json replace:@"<personality>" with:personalityJSON];
171         
172     } else {
173         json = [json replace:@"<personality>" with:@""];
174     }
175     
176     return json;
177     
178 }
179
180 #pragma mark - Build
181
182 - (BOOL)shouldBePolled {
183         return ([self.status isEqualToString:@"BUILD"] || [self.status isEqualToString:@"UNKNOWN"] || [self.status isEqualToString:@"RESIZE"] || [self.status isEqualToString:@"QUEUE_RESIZE"] || [self.status isEqualToString:@"PREP_RESIZE"] || [self.status isEqualToString:@"REBUILD"] || [self.status isEqualToString:@"REBOOT"] || [self.status isEqualToString:@"HARD_REBOOT"]);
184 }
185
186 #pragma mark -
187 #pragma mark Setters
188
189 - (void)setFlavor:(Flavor *)aFlavor {
190     if (aFlavor) {
191         flavor = aFlavor;
192         self.flavorId = self.flavor.identifier;
193         [flavor retain];
194     }
195 }
196
197 - (Image *)image {
198     if (!image) {
199         for (OpenStackAccount *account in [OpenStackAccount accounts]) {
200             Image *i = [account.images objectForKey:self.imageId];
201             if (i) {
202                 image = i;
203                 break;
204             }
205         }
206     }
207     return image;
208 }
209
210 - (void)setImage:(Image *)anImage {
211     if (anImage) {
212         image = anImage;
213         self.imageId = self.image.identifier;
214         [image retain];
215     }
216 }
217
218 #pragma mark -
219 #pragma mark Memory Management
220
221 - (void)dealloc {
222     [status release];
223     [hostId release];
224     [addresses release];
225     [metadata release];
226     [image release];
227     [flavor release];
228     [urls release];
229     [personality release];
230     [backupSchedule release];
231     [rootPassword release];
232     [flavorId release];
233     [imageId release];
234     [super dealloc];
235 }
236
237 @end