1""" Webaccelerator commands module """ 2 3from gandi.cli.core.base import GandiModule 4from gandi.cli.modules.datacenter import Datacenter 5 6 7class Webacc(GandiModule): 8 9 """ Module to handle CLI commands. 10 11 $ gandi webacc list 12 $ gandi webacc info 13 $ gandi webacc create 14 $ gandi webacc add 15 $ gandi webacc delete 16 $ gandi webacc enable 17 $ gandi webacc disable 18 $ gandi webacc probe 19 20 """ 21 22 @classmethod 23 def list(cls, options=None): 24 """ List all webaccelerator """ 25 if not options: 26 options = {} 27 return cls.call('hosting.rproxy.list', options) 28 29 @classmethod 30 def info(cls, id): 31 """ Get information about a Webaccelerator """ 32 return cls.call('hosting.rproxy.info', cls.usable_id(id)) 33 34 @classmethod 35 def create(cls, name, datacenter, backends, vhosts, algorithm, 36 ssl_enable, zone_alter): 37 """ Create a webaccelerator """ 38 datacenter_id_ = int(Datacenter.usable_id(datacenter)) 39 params = { 40 'datacenter_id': datacenter_id_, 41 'name': name, 42 'lb': {'algorithm': algorithm}, 43 'override': True, 44 'ssl_enable': ssl_enable, 45 'zone_alter': zone_alter 46 } 47 if vhosts: 48 params['vhosts'] = vhosts 49 if backends: 50 params['servers'] = backends 51 try: 52 result = cls.call('hosting.rproxy.create', params) 53 cls.echo('Creating your webaccelerator %s' % params['name']) 54 cls.display_progress(result) 55 cls.echo('Your webaccelerator have been created') 56 return result 57 except Exception as err: 58 if err.code == 580142: 59 for vhost in params['vhosts']: 60 dns_entry = cls.call( 61 'hosting.rproxy.vhost.get_dns_entries', 62 {'datacenter': datacenter_id_, 'vhost': vhost}) 63 txt_record = "@ 3600 IN TXT \"%s=%s\"" % (dns_entry['key'], 64 dns_entry['txt']) 65 66 cname_record = "%s 3600 IN CNAME %s" % (dns_entry['key'], 67 dns_entry['cname']) 68 69 cls.echo('The domain %s don\'t use Gandi DNS or you have' 70 ' not sufficient right to alter the zone file. ' 71 'Edit your zone file adding this TXT and CNAME ' 72 'record and try again :' % vhost) 73 cls.echo(txt_record) 74 cls.echo(cname_record) 75 cls.echo('\nOr add a file containing %s at :\n' 76 'http://%s/%s.txt\n' % (dns_entry['txt'], 77 dns_entry['domain'], 78 dns_entry['txt'])) 79 cls.separator_line('-', 4) 80 else: 81 cls.echo(err) 82 83 @classmethod 84 def update(cls, resource, new_name, algorithm, ssl_enable, ssl_disable): 85 """ Update a webaccelerator""" 86 params = {} 87 if new_name: 88 params['name'] = new_name 89 if algorithm: 90 params['lb'] = {'algorithm': algorithm} 91 if ssl_enable: 92 params['ssl_enable'] = ssl_enable 93 if ssl_disable: 94 params['ssl_enable'] = False 95 96 result = cls.call('hosting.rproxy.update', cls.usable_id(resource), 97 params) 98 cls.echo('Updating your webaccelerator') 99 cls.display_progress(result) 100 cls.echo('The webaccelerator have been udated') 101 return result 102 103 @classmethod 104 def delete(cls, name): 105 """ Delete a webaccelerator """ 106 result = cls.call('hosting.rproxy.delete', cls.usable_id(name)) 107 cls.echo('Deleting your webaccelerator named %s' % name) 108 cls.display_progress(result) 109 cls.echo('Webaccelerator have been deleted') 110 return result 111 112 @classmethod 113 def backend_list(cls, options): 114 """ List all servers used by webaccelerator """ 115 return cls.call('hosting.rproxy.server.list', options) 116 117 @classmethod 118 def backend_add(cls, name, backend): 119 """ Add a backend into a webaccelerator """ 120 oper = cls.call( 121 'hosting.rproxy.server.create', cls.usable_id(name), backend) 122 cls.echo('Adding backend %s:%s into webaccelerator' % 123 (backend['ip'], backend['port'])) 124 cls.display_progress(oper) 125 cls.echo('Backend added') 126 return oper 127 128 @classmethod 129 def backend_remove(cls, backend): 130 """ Remove a backend on a webaccelerator """ 131 server = cls.backend_list(backend) 132 if server: 133 oper = cls.call('hosting.rproxy.server.delete', server[0]['id']) 134 cls.echo('Removing backend %s:%s into webaccelerator' % 135 (backend['ip'], backend['port'])) 136 cls.display_progress(oper) 137 cls.echo('Your backend have been removed') 138 return oper 139 else: 140 return cls.echo('No backend found') 141 142 @classmethod 143 def backend_enable(cls, backend): 144 """ Enable a backend for a server """ 145 server = cls.backend_list(backend) 146 if server: 147 oper = cls.call('hosting.rproxy.server.enable', server[0]['id']) 148 cls.echo('Activating backend %s' % server[0]['ip']) 149 cls.display_progress(oper) 150 cls.echo('Backend activated') 151 return oper 152 else: 153 return cls.echo('No backend found') 154 155 @classmethod 156 def backend_disable(cls, backend): 157 """ Disable a backend for a server """ 158 server = cls.backend_list(backend) 159 oper = cls.call('hosting.rproxy.server.disable', 160 server[0]['id']) 161 cls.echo('Desactivating backend on server %s' % 162 server[0]['ip']) 163 cls.display_progress(oper) 164 cls.echo('Backend desactivated') 165 return oper 166 167 @classmethod 168 def vhost_list(cls): 169 """ List all vhosts used by webaccelerator """ 170 return cls.call('hosting.rproxy.vhost.list') 171 172 @classmethod 173 def vhost_add(cls, resource, params): 174 """ Add a vhost into a webaccelerator """ 175 try: 176 oper = cls.call( 177 'hosting.rproxy.vhost.create', cls.usable_id(resource), params) 178 cls.echo('Adding your virtual host (%s) into %s' % 179 (params['vhost'], resource)) 180 cls.display_progress(oper) 181 cls.echo('Your virtual host habe been added') 182 return oper 183 except Exception as err: 184 if err.code == 580142: 185 dc = cls.info(resource) 186 dns_entry = cls.call('hosting.rproxy.vhost.get_dns_entries', 187 {'datacenter': dc['datacenter']['id'], 188 'vhost': params['vhost']}) 189 txt_record = "%s 3600 IN TXT \"%s=%s\"" % (dns_entry['key'], 190 dns_entry['key'], 191 dns_entry['txt']) 192 193 cname_record = "%s 3600 IN CNAME %s" % (dns_entry['key'], 194 dns_entry['cname']) 195 196 cls.echo('The domain don\'t use Gandi DNS or you have not' 197 ' sufficient right to alter the zone file. ' 198 'Edit your zone file adding this TXT and CNAME ' 199 'record and try again :') 200 cls.echo(txt_record) 201 cls.echo(cname_record) 202 cls.echo('\nOr add a file containing %s at :\n' 203 'http://%s/%s.txt\n' % (dns_entry['txt'], 204 dns_entry['domain'], 205 dns_entry['txt'])) 206 207 else: 208 cls.echo(err) 209 210 @classmethod 211 def vhost_remove(cls, name): 212 """ Delete a vhost in a webaccelerator """ 213 oper = cls.call('hosting.rproxy.vhost.delete', name) 214 cls.echo('Deleting your virtual host %s' % name) 215 cls.display_progress(oper) 216 cls.echo('Your virtual host have been removed') 217 return oper 218 219 @classmethod 220 def probe(cls, resource, enable, disable, test, host, interval, 221 http_method, http_response, threshold, timeout, url, window): 222 """ Set a probe for a webaccelerator """ 223 params = { 224 'host': host, 225 'interval': interval, 226 'method': http_method, 227 'response': http_response, 228 'threshold': threshold, 229 'timeout': timeout, 230 'url': url, 231 'window': window 232 } 233 if enable: 234 params['enable'] = True 235 elif disable: 236 params['enable'] = False 237 if test: 238 result = cls.call( 239 'hosting.rproxy.probe.test', cls.usable_id(resource), params) 240 else: 241 result = cls.call( 242 'hosting.rproxy.probe.update', cls.usable_id(resource), params) 243 cls.display_progress(result) 244 return result 245 246 @classmethod 247 def probe_enable(cls, resource): 248 """ Activate a probe on a webaccelerator """ 249 oper = cls.call('hosting.rproxy.probe.enable', cls.usable_id(resource)) 250 cls.echo('Activating probe on %s' % resource) 251 cls.display_progress(oper) 252 cls.echo('The probe have been activated') 253 return oper 254 255 @classmethod 256 def probe_disable(cls, resource): 257 """ Disable a probe on a webaccelerator """ 258 oper = cls.call('hosting.rproxy.probe.disable', 259 cls.usable_id(resource)) 260 cls.echo('Desactivating probe on %s' % resource) 261 cls.display_progress(oper) 262 cls.echo('The probe have been desactivated') 263 return oper 264 265 @classmethod 266 def usable_id(cls, id): 267 """ Retrieve id from input which can be hostname, vhost, id. """ 268 try: 269 # id is maybe a hostname 270 qry_id = cls.from_name(id) 271 if not qry_id: 272 # id is maybe an ip 273 qry_id = cls.from_ip(id) 274 if not qry_id: 275 qry_id = cls.from_vhost(id) 276 except Exception: 277 qry_id = None 278 279 if not qry_id: 280 msg = 'unknown identifier %s' % id 281 cls.error(msg) 282 283 return qry_id 284 285 @classmethod 286 def from_name(cls, name): 287 """Retrieve webacc id associated to a webacc name.""" 288 result = cls.list({'items_per_page': 500}) 289 webaccs = {} 290 for webacc in result: 291 webaccs[webacc['name']] = webacc['id'] 292 return webaccs.get(name) 293 294 @classmethod 295 def from_ip(cls, ip): 296 """Retrieve webacc id associated to a webacc ip""" 297 result = cls.list({'items_per_page': 500}) 298 webaccs = {} 299 for webacc in result: 300 for server in webacc['servers']: 301 webaccs[server['ip']] = webacc['id'] 302 return webaccs.get(ip) 303 304 @classmethod 305 def from_vhost(cls, vhost): 306 """Retrieve webbacc id associated to a webacc vhost""" 307 result = cls.list({'items_per_page': 500}) 308 webaccs = {} 309 for webacc in result: 310 for vhost in webacc['vhosts']: 311 webaccs[vhost['name']] = webacc['id'] 312 return webaccs.get(vhost) 313