root / snf-cyclades-app / synnefo / management / common.py @ 1ec2f17e
History | View | Annotate | Download (6.2 kB)
1 | a6e6fe48 | Christos Stavrakakis | # Copyright 2012-2014 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | 11300d7b | Giorgos Verigakis | #
|
3 | 11300d7b | Giorgos Verigakis | # Redistribution and use in source and binary forms, with or
|
4 | 11300d7b | Giorgos Verigakis | # without modification, are permitted provided that the following
|
5 | 11300d7b | Giorgos Verigakis | # conditions are met:
|
6 | 11300d7b | Giorgos Verigakis | #
|
7 | 11300d7b | Giorgos Verigakis | # 1. Redistributions of source code must retain the above
|
8 | 11300d7b | Giorgos Verigakis | # copyright notice, this list of conditions and the following
|
9 | 11300d7b | Giorgos Verigakis | # disclaimer.
|
10 | 11300d7b | Giorgos Verigakis | #
|
11 | 11300d7b | Giorgos Verigakis | # 2. Redistributions in binary form must reproduce the above
|
12 | 11300d7b | Giorgos Verigakis | # copyright notice, this list of conditions and the following
|
13 | 11300d7b | Giorgos Verigakis | # disclaimer in the documentation and/or other materials
|
14 | 11300d7b | Giorgos Verigakis | # provided with the distribution.
|
15 | 11300d7b | Giorgos Verigakis | #
|
16 | 11300d7b | Giorgos Verigakis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | 11300d7b | Giorgos Verigakis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | 11300d7b | Giorgos Verigakis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | 11300d7b | Giorgos Verigakis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | 11300d7b | Giorgos Verigakis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | 11300d7b | Giorgos Verigakis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | 11300d7b | Giorgos Verigakis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | 11300d7b | Giorgos Verigakis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | 11300d7b | Giorgos Verigakis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | 11300d7b | Giorgos Verigakis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | 11300d7b | Giorgos Verigakis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | 11300d7b | Giorgos Verigakis | # POSSIBILITY OF SUCH DAMAGE.
|
28 | 11300d7b | Giorgos Verigakis | #
|
29 | 11300d7b | Giorgos Verigakis | # The views and conclusions contained in the software and
|
30 | 11300d7b | Giorgos Verigakis | # documentation are those of the authors and should not be
|
31 | 11300d7b | Giorgos Verigakis | # interpreted as representing official policies, either expressed
|
32 | 11300d7b | Giorgos Verigakis | # or implied, of GRNET S.A.
|
33 | 11300d7b | Giorgos Verigakis | |
34 | 53b9ba10 | Christos Stavrakakis | from django.core.management import CommandError |
35 | 9d1e6480 | Marios Kogias | from synnefo.db.models import (Backend, VirtualMachine, Network, |
36 | b48697f0 | Christos Stavrakakis | Flavor, IPAddress, Subnet, |
37 | 09b76b7e | Christos Stavrakakis | BridgePoolTable, MacPrefixPoolTable, |
38 | a6e6fe48 | Christos Stavrakakis | NetworkInterface) |
39 | c75ab92e | Christos Stavrakakis | from functools import wraps |
40 | bad9404c | Christos Stavrakakis | |
41 | a6e6fe48 | Christos Stavrakakis | from django.conf import settings |
42 | bd40abfa | Christos Stavrakakis | from snf_django.lib.api import faults |
43 | bcd80cd9 | Christos Stavrakakis | from synnefo.api import util |
44 | 35f2fc07 | Christos Stavrakakis | from synnefo.logic import backend as backend_mod |
45 | 2333a2c4 | Christos Stavrakakis | from synnefo.logic.rapi import GanetiApiError, GanetiRapiClient |
46 | 0252fb8b | Christos Stavrakakis | from synnefo.logic.utils import (id_from_instance_name, |
47 | a6e6fe48 | Christos Stavrakakis | id_from_network_name, |
48 | a6e6fe48 | Christos Stavrakakis | id_from_nic_name) |
49 | a6e6fe48 | Christos Stavrakakis | from django.core.exceptions import ObjectDoesNotExist |
50 | 8814e07c | Christos Stavrakakis | import logging |
51 | 8814e07c | Christos Stavrakakis | log = logging.getLogger(__name__) |
52 | 8814e07c | Christos Stavrakakis | |
53 | 11300d7b | Giorgos Verigakis | |
54 | f66d8b04 | Christos Stavrakakis | def format_vm_state(vm): |
55 | f66d8b04 | Christos Stavrakakis | if vm.operstate == "BUILD": |
56 | f66d8b04 | Christos Stavrakakis | return "BUILD(" + str(vm.buildpercentage) + "%)" |
57 | f66d8b04 | Christos Stavrakakis | else:
|
58 | f66d8b04 | Christos Stavrakakis | return vm.operstate
|
59 | 53b9ba10 | Christos Stavrakakis | |
60 | a6e6fe48 | Christos Stavrakakis | RESOURCE_MAP = { |
61 | a6e6fe48 | Christos Stavrakakis | "backend": Backend.objects,
|
62 | a6e6fe48 | Christos Stavrakakis | "flavor": Flavor.objects,
|
63 | a6e6fe48 | Christos Stavrakakis | "server": VirtualMachine.objects,
|
64 | a6e6fe48 | Christos Stavrakakis | "network": Network.objects,
|
65 | a6e6fe48 | Christos Stavrakakis | "subnet": Subnet.objects,
|
66 | a6e6fe48 | Christos Stavrakakis | "port": NetworkInterface.objects,
|
67 | a6e6fe48 | Christos Stavrakakis | "floating-ip": IPAddress.objects.filter(floating_ip=True)} |
68 | a6e6fe48 | Christos Stavrakakis | |
69 | a6e6fe48 | Christos Stavrakakis | |
70 | a6e6fe48 | Christos Stavrakakis | def get_resource(name, value, for_update=False): |
71 | a6e6fe48 | Christos Stavrakakis | """Get object from DB based by it's ID
|
72 | a6e6fe48 | Christos Stavrakakis |
|
73 | a6e6fe48 | Christos Stavrakakis | Helper function for getting an object from DB by it's DB and raising
|
74 | a6e6fe48 | Christos Stavrakakis | appropriate command line errors if the object does not exist or the
|
75 | a6e6fe48 | Christos Stavrakakis | ID is invalid.
|
76 | a6e6fe48 | Christos Stavrakakis |
|
77 | a6e6fe48 | Christos Stavrakakis | """
|
78 | a6e6fe48 | Christos Stavrakakis | objects = RESOURCE_MAP[name] |
79 | a6e6fe48 | Christos Stavrakakis | if name == "floating-ip": |
80 | a6e6fe48 | Christos Stavrakakis | capital_name = "Floating IP"
|
81 | a6e6fe48 | Christos Stavrakakis | else:
|
82 | a6e6fe48 | Christos Stavrakakis | capital_name = name.capitalize() |
83 | a6e6fe48 | Christos Stavrakakis | |
84 | 1ec2f17e | Christos Stavrakakis | if isinstance(value, basestring) and name in ["server", "network", "port"]: |
85 | 1ec2f17e | Christos Stavrakakis | if value.startswith(settings.BACKEND_PREFIX_ID):
|
86 | 1ec2f17e | Christos Stavrakakis | try:
|
87 | a6e6fe48 | Christos Stavrakakis | if name == "server": |
88 | a6e6fe48 | Christos Stavrakakis | value = id_from_instance_name(value) |
89 | a6e6fe48 | Christos Stavrakakis | elif name == "network": |
90 | a6e6fe48 | Christos Stavrakakis | value = id_from_network_name(value) |
91 | a6e6fe48 | Christos Stavrakakis | elif name == "port": |
92 | a6e6fe48 | Christos Stavrakakis | value = id_from_nic_name(value) |
93 | 1ec2f17e | Christos Stavrakakis | except ValueError: |
94 | 1ec2f17e | Christos Stavrakakis | raise CommandError("Invalid {} ID: {}".format(capital_name, |
95 | 1ec2f17e | Christos Stavrakakis | value)) |
96 | 53b9ba10 | Christos Stavrakakis | |
97 | a6e6fe48 | Christos Stavrakakis | if for_update:
|
98 | a6e6fe48 | Christos Stavrakakis | objects = objects.select_for_update() |
99 | b84ed662 | Christos Stavrakakis | try:
|
100 | a6e6fe48 | Christos Stavrakakis | return objects.get(id=value)
|
101 | a6e6fe48 | Christos Stavrakakis | except ObjectDoesNotExist:
|
102 | a6e6fe48 | Christos Stavrakakis | msg = ("{0} with ID {1} does not exist. Use {2}-list to find out"
|
103 | a6e6fe48 | Christos Stavrakakis | " available {2} IDs.")
|
104 | a6e6fe48 | Christos Stavrakakis | raise CommandError(msg.format(capital_name, value, name))
|
105 | a6e6fe48 | Christos Stavrakakis | except (ValueError, TypeError): |
106 | a6e6fe48 | Christos Stavrakakis | raise CommandError("Invalid {} ID: {}".format(capital_name, value)) |
107 | b84ed662 | Christos Stavrakakis | |
108 | b84ed662 | Christos Stavrakakis | |
109 | b84ed662 | Christos Stavrakakis | def get_image(image_id, user_id): |
110 | b84ed662 | Christos Stavrakakis | if image_id:
|
111 | b84ed662 | Christos Stavrakakis | try:
|
112 | bcd80cd9 | Christos Stavrakakis | return util.get_image_dict(image_id, user_id)
|
113 | bd40abfa | Christos Stavrakakis | except faults.ItemNotFound:
|
114 | b84ed662 | Christos Stavrakakis | raise CommandError("Image with ID %s not found." |
115 | b84ed662 | Christos Stavrakakis | " Use snf-manage image-list to find"
|
116 | b84ed662 | Christos Stavrakakis | " out available image IDs." % image_id)
|
117 | b84ed662 | Christos Stavrakakis | else:
|
118 | b84ed662 | Christos Stavrakakis | raise CommandError("image-id is mandatory") |
119 | b84ed662 | Christos Stavrakakis | |
120 | b84ed662 | Christos Stavrakakis | |
121 | 2333a2c4 | Christos Stavrakakis | def check_backend_credentials(clustername, port, username, password): |
122 | 2333a2c4 | Christos Stavrakakis | try:
|
123 | 2333a2c4 | Christos Stavrakakis | client = GanetiRapiClient(clustername, port, username, password) |
124 | 2333a2c4 | Christos Stavrakakis | # This command will raise an exception if there is no
|
125 | 2333a2c4 | Christos Stavrakakis | # write-access
|
126 | 2333a2c4 | Christos Stavrakakis | client.ModifyCluster() |
127 | 2333a2c4 | Christos Stavrakakis | except GanetiApiError as e: |
128 | 2333a2c4 | Christos Stavrakakis | raise CommandError(e)
|
129 | 2333a2c4 | Christos Stavrakakis | |
130 | 2333a2c4 | Christos Stavrakakis | info = client.GetInfo() |
131 | 2333a2c4 | Christos Stavrakakis | info_name = info['name']
|
132 | 2333a2c4 | Christos Stavrakakis | if info_name != clustername:
|
133 | 2333a2c4 | Christos Stavrakakis | raise CommandError("Invalid clustername value. Please use the" |
134 | 2333a2c4 | Christos Stavrakakis | " Ganeti Cluster name: %s" % info_name)
|
135 | 7a0aa449 | Christos Stavrakakis | |
136 | 7a0aa449 | Christos Stavrakakis | |
137 | c75ab92e | Christos Stavrakakis | def convert_api_faults(func): |
138 | c75ab92e | Christos Stavrakakis | @wraps(func)
|
139 | c75ab92e | Christos Stavrakakis | def wrapper(*args, **kwargs): |
140 | c75ab92e | Christos Stavrakakis | try:
|
141 | c75ab92e | Christos Stavrakakis | return func(*args, **kwargs)
|
142 | c75ab92e | Christos Stavrakakis | except faults.Fault as e: |
143 | c75ab92e | Christos Stavrakakis | raise CommandError(e.message)
|
144 | c75ab92e | Christos Stavrakakis | return wrapper
|
145 | c75ab92e | Christos Stavrakakis | |
146 | c75ab92e | Christos Stavrakakis | |
147 | 4500650c | Stratos Psomadakis | class Omit(object): |
148 | 4500650c | Stratos Psomadakis | pass
|
149 | 35f2fc07 | Christos Stavrakakis | |
150 | 35f2fc07 | Christos Stavrakakis | |
151 | 35f2fc07 | Christos Stavrakakis | def wait_server_task(server, wait, stdout): |
152 | 35f2fc07 | Christos Stavrakakis | jobID = server.task_job_id |
153 | 371ab004 | Christos Stavrakakis | if jobID is None: |
154 | 371ab004 | Christos Stavrakakis | return
|
155 | 35f2fc07 | Christos Stavrakakis | if wait:
|
156 | 35f2fc07 | Christos Stavrakakis | msg = "Issued job '%s'. Waiting to complete...\n"
|
157 | 35f2fc07 | Christos Stavrakakis | stdout.write(msg % jobID) |
158 | 35f2fc07 | Christos Stavrakakis | client = server.get_client() |
159 | 35f2fc07 | Christos Stavrakakis | wait_ganeti_job(client, jobID, stdout) |
160 | 35f2fc07 | Christos Stavrakakis | else:
|
161 | 35f2fc07 | Christos Stavrakakis | msg = "Issued job '%s'.\n"
|
162 | 35f2fc07 | Christos Stavrakakis | stdout.write(msg % jobID) |
163 | 35f2fc07 | Christos Stavrakakis | |
164 | 35f2fc07 | Christos Stavrakakis | |
165 | 35f2fc07 | Christos Stavrakakis | def wait_ganeti_job(client, jobID, stdout): |
166 | 35f2fc07 | Christos Stavrakakis | status, error = backend_mod.wait_for_job(client, jobID) |
167 | 35f2fc07 | Christos Stavrakakis | if status == "success": |
168 | 35f2fc07 | Christos Stavrakakis | stdout.write("Job finished successfully.\n")
|
169 | 35f2fc07 | Christos Stavrakakis | else:
|
170 | 35f2fc07 | Christos Stavrakakis | raise CommandError("Job failed! Error: %s\n" % error) |
171 | b48697f0 | Christos Stavrakakis | |
172 | b48697f0 | Christos Stavrakakis | |
173 | b48697f0 | Christos Stavrakakis | def pool_table_from_type(type_): |
174 | b48697f0 | Christos Stavrakakis | if type_ == "mac-prefix": |
175 | b48697f0 | Christos Stavrakakis | return MacPrefixPoolTable
|
176 | b48697f0 | Christos Stavrakakis | elif type_ == "bridge": |
177 | b48697f0 | Christos Stavrakakis | return BridgePoolTable
|
178 | b48697f0 | Christos Stavrakakis | # elif type == "ip":
|
179 | b48697f0 | Christos Stavrakakis | # return IPPoolTable
|
180 | b48697f0 | Christos Stavrakakis | else:
|
181 | b48697f0 | Christos Stavrakakis | raise ValueError("Invalid pool type") |