Bug 259 Support port_security in Openmano
[osm/SO.git] / rwcal / rift / cal / cloudsim
1 #!/usr/bin/env python3
2
3 import argparse
4 import logging
5 import os
6 import sys
7
8 import gi
9 gi.require_version('RwcalYang', '1.0')
10 gi.require_version('RwCal', '1.0')
11 gi.require_version('RwLog', '1.0')
12
13 import rift.cal.server as cal_server
14 import rift.cal.client as cal_client
15 import rift.cal.utils as cal_utils
16 import rift.rwcal.cloudsim.lxc as lxc
17 import rift.rwcal.cloudsim.lvm as lvm
18 import rift.rwcal.cloudsim.shell as shell
19
20 from prettytable import PrettyTable
21
22
23 START_PARSER = "start"
24 STOP_PARSER = "stop"
25 CLEAN_PARSER = "clean"
26 FCLEAN_PARSER = "force-clean"
27 IMAGE_PARSER = "image-create"
28 STATUS_PARSER = "status"
29
30
31 class CloudsimOperations(cal_utils.CloudSimCalMixin):
32     def __init__(self, args):
33         super().__init__()
34         self.log = cal_utils.Logger(
35                     daemon_mode=False,
36                     log_name="Parser",
37                     log_level=logging.getLevelName(args.log_level)).logger
38
39         self.args = args
40         self.operations = cal_server.CloudsimServerOperations(self.log)
41         self.client = cal_client.CloudsimClient(self.log)
42         self._cal, self._account = None, None
43
44     @property
45     def log_file(self):
46         return cal_utils.Logger.LOG_FILE
47
48     @cal_utils.check_and_create_bridge
49     def start_server(self):
50         self.operations.start_server(foreground=self.args.foreground)
51
52     @cal_utils.check_and_create_bridge
53     def stop_server(self):
54         self.operations.stop_server()
55
56     @cal_utils.check_and_create_bridge
57     def clean_resources(self):
58         """Clean all resource using rest APIs. """
59         self.operations.clean_server(images=self.args.all)
60
61     @cal_utils.check_and_create_bridge
62     def upload_image(self):
63         """Onboard image to cloudsim server."""
64         self.client.upload_image(self.args.location, name=self.args.name)
65
66     def force_clean_resources(self):
67         """Force clean up all resource. """
68         self.log.info("Cleaning up logs")
69         shell.command("rm -f {}".format(self.log_file))
70
71         self.log.info("Cleaning up PID file")
72         shell.command("rm -f {}".format(self.operations.PID_FILE))
73
74         try:
75             self.log.info("Purging LXC resources")
76             for container in lxc.containers():
77                 lxc.stop(container)
78
79             for container in lxc.containers():
80                 lxc.destroy(container)
81
82             lvm.destroy('rift')
83
84         except shell.ProcessError:
85             self.log.exception("Unable to purge resources. Trying a force clean now.")
86             lxc.force_clean()
87
88     @cal_utils.check_and_create_bridge
89     def show_status(self):
90
91         cld_tbl = PrettyTable(['PID', 'Status', 'Log file'])
92
93         pid = self.operations.pid
94         if pid:
95             cld_tbl.add_row([pid, "RUNNING", self.log_file])
96         else:
97             cld_tbl.add_row(["-", "STOPPED", self.log_file])
98
99         print ("Cloudsim server:")
100         print (cld_tbl)
101
102         if not pid:
103             return
104
105         # Images
106         img_tbl = PrettyTable(['ID', 'Name', 'Format'])
107         vlink_tbl = PrettyTable([
108                 'ID', 'Name', 'Bridge Name', 'State', 'Subnet', 'Ports', "IPs"])
109         vdu_tbl = PrettyTable([
110             'ID', 'Name', 'LXC Name', 'IP', 'State', 'Ports', "VLink ID"])
111
112
113         images = self.client.images
114         if images:
115             for image in images:
116                 img_tbl.add_row([image.id, image.name, image.disk_format])
117
118             print ("Images:")
119             print (img_tbl)
120
121         vlinks = self.client.vlinks
122         if vlinks:
123             for vlink in vlinks:
124
125                 ports, ips = [], []
126                 for cp in vlink.connection_points:
127                     ports.append("{} ({})".format(cp.name, cp.connection_point_id))
128                     ips.append(cp.ip_address)
129
130                 vlink_tbl.add_row([
131                     vlink.virtual_link_id,
132                     vlink.name,
133                     vlink.name[:15],
134                     vlink.state,
135                     vlink.subnet,
136                     "\n".join(ports),
137                     "\n".join(ips)])
138
139             print ("Vlink:")
140             print (vlink_tbl)
141
142
143         lxc_to_ip = lxc.ls_info()
144         def get_lxc_name(ip):
145             for lxc_name, ips in lxc_to_ip.items():
146                 if str(ip) in ips:
147                     return lxc_name
148
149             return ""
150
151         vdus = self.client.vdus
152         if vdus:
153             for vdu in vdus:
154                 ports, links = [], []
155                 for cp in vdu.connection_points:
156                     ports.append("{} ({})".format(cp.name, cp.ip_address))
157                     links.append(cp.virtual_link_id)
158
159                 vdu_tbl.add_row([
160                     vdu.vdu_id, vdu.name, get_lxc_name(vdu.public_ip), vdu.public_ip,
161                     vdu.state, "\n".join(ports), "\n".join(links)])
162
163             print ("VDU:")
164             print (vdu_tbl)
165
166
167 def parse(arguments):
168     parser = argparse.ArgumentParser(description=__doc__,
169                                     formatter_class=argparse.RawDescriptionHelpFormatter)
170     parser.add_argument(
171             '--log-level', '-l',
172             default="WARNING",
173             type=str,
174             choices=["INFO", "DEBUG", "WARNING", "ERROR"],
175             help="Set log level, defaults to warning and above.")
176
177     subparsers = parser.add_subparsers()
178
179     start_parser = subparsers.add_parser(START_PARSER, help="Start the server")
180     start_parser.add_argument(
181             '--foreground', "-f",
182             help="Run the server in the foreground. The logs are sent to console.",
183             default=False,
184             action="store_true")
185     start_parser.set_defaults(which=START_PARSER)
186
187     stop_parser = subparsers.add_parser(STOP_PARSER, help="Stop the server")
188     stop_parser.set_defaults(which=STOP_PARSER)
189
190     clean_parser = subparsers.add_parser(
191             CLEAN_PARSER,
192             help="Clean LXC resources. By default all resources except " + \
193                  "images are cleared.")
194     clean_parser.add_argument(
195             '--all', '-a', 
196             help="Cleans up all resources including images",
197             default=False,
198             action="store_true")
199     clean_parser.set_defaults(which=CLEAN_PARSER)
200
201     fclean_parser = subparsers.add_parser(
202             FCLEAN_PARSER,
203             help="Force clean all lxc resources")
204     fclean_parser.set_defaults(which=FCLEAN_PARSER)
205
206     image_parser = subparsers.add_parser(IMAGE_PARSER, help="Upload images")
207     image_parser.add_argument(
208             '--name', '-n',
209             help="(Optional) Name of the image")
210     image_parser.add_argument(
211             '--location', '-l',
212             help="Image location. If name is not specified the basename of " + \
213                  "the image path is used.",
214             required=True)
215     image_parser.set_defaults(which=IMAGE_PARSER)
216
217     show_parser = subparsers.add_parser(
218             STATUS_PARSER,
219             help="Shows the current status of LXC")
220     show_parser.set_defaults(which=STATUS_PARSER)
221
222     args = parser.parse_args(arguments)
223
224     return args
225
226
227 def main(args):
228
229     args = parse(args)
230
231     operations = CloudsimOperations(args)
232
233     if args.which == START_PARSER:
234         operations.start_server()
235     elif args.which == STOP_PARSER:
236         operations.stop_server()
237     elif args.which == FCLEAN_PARSER:
238         operations.force_clean_resources()
239     elif args.which == CLEAN_PARSER:
240         operations.clean_resources()
241     elif args.which == IMAGE_PARSER:
242         operations.upload_image()
243     elif args.which == STATUS_PARSER:
244         operations.show_status()
245
246
247 if __name__ == "__main__":
248     main(sys.argv[1:])