55# to you under the Apache License, Version 2.0 (the
66# "License"); you may not use this file except in compliance
77# with the License. You may obtain a copy of the License at
8- #
8+ #
99# http://www.apache.org/licenses/LICENSE-2.0
10- #
10+ #
1111# Unless required by applicable law or agreed to in writing,
1212# software distributed under the License is distributed on an
1313# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414# KIND, either express or implied. See the License for the
1515# specific language governing permissions and limitations
1616# under the License.
1717
18-
18+
1919
2020'''Implements the CloudStack API'''
2121
3232import httplib
3333
3434class CloudAPI :
35-
35+
3636 @describe ("server" , "Management Server host name or address" )
3737 @describe ("apikey" , "Management Server apiKey" )
3838 @describe ("securitykey" , "Management Server securityKey" )
@@ -46,14 +46,14 @@ def __init__(self,
4646 securityKey = None
4747 ):
4848 self .__dict__ .update (locals ())
49-
49+
5050 def _make_request_with_keys (self ,command ,requests = {}):
5151 requests ["command" ] = command
5252 requests ["apiKey" ] = self .apiKey
5353 requests ["response" ] = "xml"
5454 requests = zip (requests .keys (), requests .values ())
5555 requests .sort (key = lambda x : str .lower (x [0 ]))
56-
56+
5757 requestUrl = "&" .join (["=" .join ([request [0 ], urllib .quote_plus (str (request [1 ]))]) for request in requests ])
5858 hashStr = "&" .join (["=" .join ([str .lower (request [0 ]), urllib .quote_plus (str .lower (str (request [1 ])))]) for request in requests ])
5959
@@ -70,7 +70,7 @@ def _make_request_with_auth(self, command, requests):
7070 requests ["response" ] = self .responseformat
7171 requests = zip (requests .keys (), requests .values ())
7272 requests .sort (key = lambda x : str .lower (x [0 ]))
73-
73+
7474 requestUrl = "&" .join (["=" .join ([request [0 ], urllib .quote_plus (str (request [1 ]))]) for request in requests ])
7575 hashStr = "&" .join (["=" .join ([str .lower (request [0 ]), urllib .quote_plus (str .lower (str (request [1 ])))]) for request in requests ])
7676
@@ -80,7 +80,7 @@ def _make_request_with_auth(self, command, requests):
8080
8181 self .connection .request ("GET" , "/client/api?%s" % requestUrl )
8282 return self .connection .getresponse ().read ()
83-
83+
8484 def _make_request (self ,command ,parameters = None ):
8585
8686 '''Command is a string, parameters is a dictionary'''
@@ -90,9 +90,9 @@ def _make_request(self,command,parameters=None):
9090 else :
9191 host = self .server
9292 port = 8096
93-
94- url = "http://" + self .server + "/?"
95-
93+
94+ url = "http://" + self .server + "/client/api ?"
95+
9696 if not parameters : parameters = {}
9797 if self .apiKey is not None and self .securityKey is not None :
9898 return self ._make_request_with_auth (command , parameters )
@@ -102,7 +102,7 @@ def _make_request(self,command,parameters=None):
102102 querystring = urllib .urlencode (parameters )
103103
104104 url += querystring
105-
105+
106106 f = urllib2 .urlopen (url )
107107 data = f .read ()
108108 if self .stripxml == "true" :
@@ -119,59 +119,59 @@ def _make_request(self,command,parameters=None):
119119
120120def load_dynamic_methods ():
121121 '''creates smart function objects for every method in the commands.xml file'''
122-
122+
123123 def getText (nodelist ):
124124 rc = []
125125 for node in nodelist :
126126 if node .nodeType == node .TEXT_NODE : rc .append (node .data )
127127 return '' .join (rc )
128-
128+
129129 # FIXME figure out installation and packaging
130130 xmlfile = os .path .join ("/etc/cloud/cli/" ,"commands.xml" )
131131 dom = xml .dom .minidom .parse (xmlfile )
132-
132+
133133 for cmd in dom .getElementsByTagName ("command" ):
134134 name = getText (cmd .getElementsByTagName ('name' )[0 ].childNodes ).strip ()
135135 assert name
136-
136+
137137 description = getText (cmd .getElementsByTagName ('description' )[0 ].childNodes ).strip ()
138- if description :
138+ if description :
139139 description = '"""%s"""' % description
140140 else : description = ''
141141 arguments = []
142142 options = []
143143 descriptions = []
144-
144+
145145 for param in cmd .getElementsByTagName ("request" )[0 ].getElementsByTagName ("arg" ):
146146 argname = getText (param .getElementsByTagName ('name' )[0 ].childNodes ).strip ()
147147 assert argname
148-
148+
149149 required = getText (param .getElementsByTagName ('required' )[0 ].childNodes ).strip ()
150150 if required == 'true' : required = True
151151 elif required == 'false' : required = False
152152 else : raise AssertionError , "Not reached"
153153 if required : arguments .append (argname )
154154 options .append (argname )
155-
155+
156156 #import ipdb; ipdb.set_trace()
157157 requestDescription = param .getElementsByTagName ('description' )
158- if requestDescription :
158+ if requestDescription :
159159 descriptionParam = getText (requestDescription [0 ].childNodes )
160- else :
160+ else :
161161 descriptionParam = ''
162162 if descriptionParam : descriptions .append ( (argname ,descriptionParam ) )
163-
163+
164164 funcparams = ["self" ] + [ "%s=None" % o for o in options ]
165165 funcparams = ", " .join (funcparams )
166-
166+
167167 code = """
168168 def %s(%s):
169169 %s
170170 parms = dict(locals())
171171 del parms["self"]
172172 for arg in %r:
173173 if locals()[arg] is None:
174- raise TypeError, "%%s is a required option"%%arg
174+ raise TypeError, "%%s is a required option"%%arg
175175 for k,v in parms.items():
176176 if v is None: del parms[k]
177177 output = self._make_request("%s",parms)
@@ -180,15 +180,15 @@ def %s(%s):
180180
181181 namespace = {}
182182 exec code .strip () in namespace
183-
183+
184184 func = namespace [name ]
185185 for argname ,description in descriptions :
186186 func = describe (argname ,description )(func )
187-
187+
188188 yield (name ,func )
189189
190190
191- for name ,meth in load_dynamic_methods ():
191+ for name ,meth in load_dynamic_methods ():
192192 setattr (CloudAPI , name , meth )
193193
194194implementor = CloudAPI
0 commit comments