def handle(self, *args, **options): if args: raise CommandError("Command doesn't accept any arguments") name = options['name'] user_id = options['user_id'] backend_id = options['backend_id'] image_id = options['image_id'] flavor_id = options['flavor_id'] password = options['password'] if not name: raise CommandError("name is mandatory") if not user_id: raise CommandError("user-id is mandatory") if not password: raise CommandError("password is mandatory") if not flavor_id: raise CommandError("flavor-id is mandatory") if not image_id: raise CommandError("image-id is mandatory") flavor = common.get_flavor(flavor_id) image = common.get_image(image_id, user_id) if backend_id: backend = common.get_backend(backend_id) do_create_server(user_id, name, password, flavor, image, backend=backend)
def handle(self, *args, **options): write = self.stdout.write if len(args) < 1: raise CommandError("Please provide a backend ID") backend = get_backend(args[0]) write("Trying to remove backend: %s\n" % backend.clustername) if backend.virtual_machines.filter(deleted=False).exists(): raise CommandError('Backend hosts non-deleted vms. Cannot delete') # Get networks before deleting backend, because after deleting the # backend, all BackendNetwork objects are deleted! networks = [bn.network for bn in backend.networks.all()] try: delete_backend(backend) except models.ProtectedError as e: msg = ("Cannot delete backend because it contains" "non-deleted VMs:\n%s" % e) raise CommandError(msg) write('Successfully removed backend from DB.\n') if networks: write("Clearing networks from %s..\n" % backend.clustername) for network in networks: backend_mod.delete_network(network=network, backend=backend) write("Successfully issued jobs to remove all networks.\n")
def handle(self, *args, **options): if args: raise CommandError("Command doesn't accept any arguments") name = options['name'] user_id = options['user_id'] backend_id = options['backend_id'] image_id = options['image_id'] flavor_id = options['flavor_id'] password = options['password'] if not name: raise CommandError("name is mandatory") if not user_id: raise CommandError("user-id is mandatory") if not password: raise CommandError("password is mandatory") if not flavor_id: raise CommandError("flavor-id is mandatory") if not image_id: raise CommandError("image-id is mandatory") flavor = common.get_flavor(flavor_id) image = common.get_image(image_id, user_id) if backend_id: backend = common.get_backend(backend_id) else: backend = None do_create_server(user_id, name, password, flavor, image, backend=backend)
def handle(self, *args, **options): write = self.stdout.write if len(args) < 1: raise CommandError("Please provide a backend ID") backend = get_backend(args[0]) write('Trying to remove backend: %s\n' % backend.clustername) vms_in_backend = VirtualMachine.objects.filter(backend=backend, deleted=False) if vms_in_backend: raise CommandError('Backend hosts non-deleted vms. Can not delete') networks = BackendNetwork.objects.filter(backend=backend, deleted=False) networks = [net.network.backend_id for net in networks] backend.delete() write('Successfully removed backend.\n') if networks: write('Left the following orphans networks in Ganeti:\n') write(' ' + '\n * '.join(networks) + '\n') write('Manually remove them.\n')
def handle(self, *args, **options): if len(args) != 1: raise CommandError("Please provide a backend ID") backend = get_backend(args[0]) # Ensure fields correspondence with options and Backend model credentials_changed = False fields = ('clustername', 'port', 'username', 'password') for field in fields: value = options.get(field) if value is not None: backend.__setattr__(field, value) credentials_changed = True if credentials_changed: # check credentials, if any of them changed! check_backend_credentials(backend.clustername, backend.port, backend.username, backend.password) if options['drained']: backend.drained = parse_bool(options['drained'], strict=True) if options['offline']: backend.offline = parse_bool(options['offline'], strict=True) hypervisor = options["hypervisor"] if hypervisor: backend.hypervisor = hypervisor backend.save()
def handle(self, *args, **options): if options["backend"] is not None: backend = get_backend(options["backend"]) else: backend = None clusters = parse_bool(options["clusters"]) servers = parse_bool(options["servers"]) images = parse_bool(options["images"]) if backend is None: ip_pools = parse_bool(options["ip_pools"]) networks = parse_bool(options["networks"]) else: ip_pools = False networks = False if options["json_file"] is None: stats = statistics.get_cyclades_stats(backend, clusters, servers, ip_pools, networks, images) else: with open(options["json_file"]) as data_file: stats = json.load(data_file) output_format = options["output_format"] if output_format == "json": self.stdout.write(json.dumps(stats, indent=4) + "\n") elif output_format == "pretty": cluster_details = parse_bool(options["cluster_details"]) pretty_print_stats(stats, self.stdout, cluster_details=cluster_details) else: raise CommandError("Output format '%s' not supported." % output_format)
def handle(self, *args, **options): if len(args) != 1: raise CommandError("Please provide a backend ID") backend = get_backend(args[0]) # Ensure fields correspondence with options and Backend model credentials_changed = False fields = ("clustername", "port", "username", "password") for field in fields: value = options.get(field) if value is not None: backend.__setattr__(field, value) credentials_changed = True if credentials_changed: # check credentials, if any of them changed! check_backend_credentials(backend.clustername, backend.port, backend.username, backend.password) if options["drained"]: backend.drained = parse_bool(options["drained"], strict=True) if options["offline"]: backend.offline = parse_bool(options["offline"], strict=True) hypervisor = options["hypervisor"] if hypervisor: backend.hypervisor = hypervisor backend.save()
def import_server(instance_name, backend_id, flavor_id, image_id, user_id, new_public_nic, stream=sys.stdout): flavor = common.get_flavor(flavor_id) backend = common.get_backend(backend_id) backend_client = backend.get_client() try: instance = backend_client.GetInstance(instance_name) except GanetiApiError as e: if e.code == 404: raise CommandError("Instance %s does not exist in backend %s" % (instance_name, backend)) else: raise CommandError("Unexpected error" + str(e)) if not new_public_nic: check_instance_nics(instance) shutdown_instance(instance, backend_client, stream=stream) # Create the VM in DB stream.write("Creating VM entry in DB\n") vm = VirtualMachine.objects.create(name=instance_name, backend=backend, userid=user_id, imageid=image_id, flavor=flavor) quotas.issue_and_accept_commission(vm) if new_public_nic: remove_instance_nics(instance, backend_client, stream=stream) # Rename instance rename_instance(instance_name, vm.backend_vm_id, backend_client, stream) if new_public_nic: ports = servers.create_instance_ports(user_id) stream.write("Adding new NICs to server") [servers.associate_port_with_machine(port, vm) for port in ports] [connect_to_network(vm, port) for port in ports] # Startup instance startup_instance(vm.backend_vm_id, backend_client, stream=stream) backend.put_client(backend_client) return
def import_server(instance_name, backend_id, flavor_id, image_id, user_id, new_public_nic, stream=sys.stdout): flavor = common.get_flavor(flavor_id) backend = common.get_backend(backend_id) backend_client = backend.get_client() try: instance = backend_client.GetInstance(instance_name) except GanetiApiError as e: if e.code == 404: raise CommandError("Instance %s does not exist in backend %s" % (instance_name, backend)) else: raise CommandError("Unexpected error" + str(e)) if new_public_nic: remove_instance_nics(instance, backend_client, stream=stream) (network, address) = allocate_public_address(backend) if address is None: raise CommandError("Can not allocate a public address." " No available public network.") nic = {'ip': address, 'network': network.backend_id} add_public_nic(instance_name, nic, backend_client, stream=stream) else: check_instance_nics(instance) shutdown_instance(instance, backend_client, stream=stream) # Create the VM in DB stream.write("Creating VM entry in DB\n") vm = VirtualMachine.objects.create(name=instance_name, backend=backend, userid=user_id, imageid=image_id, flavor=flavor) quotas.issue_and_accept_commission(vm) # Rename instance rename_instance(instance_name, vm.backend_vm_id, backend_client, stream) # Startup instance startup_instance(vm.backend_vm_id, backend_client, stream=stream) backend.put_client(backend_client) return
def handle_args(self, *args, **options): if options["suspended"]: self.filters["suspended"] = True if options["backend_id"]: backend = get_backend(options["backend_id"]) self.filters["backend"] = backend.id if options["build"]: self.filters["operstate"] = "BUILD" if options["image_name"]: self.fields = ["image.name" if x == "image.id" else x for x in self.fields]
def handle_args(self, *args, **options): if options["suspended"]: self.filters["suspended"] = True if options["backend_id"]: backend = get_backend(options["backend_id"]) self.filters["backend"] = backend.id if options["build"]: self.filters["operstate"] = "BUILD" if options["image_name"]: self.fields = ["image.name" if x == "image.id" else x for x in self.fields] if "ipv4" in self.fields or "ipv6" in self.fields: self.prefetch_related.append("nics__ips__subnet")
def handle(self, **options): backend_id = options['backend-id'] if backend_id: backends = [get_backend(backend_id)] else: backends = reconciliation.get_online_backends() parallel = parse_bool(options["parallel"]) if parallel and len(backends) > 1: cmd = sys.argv processes = [] for backend in backends: p = subprocess.Popen(cmd + ["--backend-id=%s" % backend.id]) processes.append(p) for p in processes: p.wait() return verbosity = int(options["verbosity"]) logger = logging.getLogger("reconcile-servers") logger.propagate = 0 formatter = logging.Formatter("%(message)s") log_handler = logging.StreamHandler() log_handler.setFormatter(formatter) if verbosity == 2: formatter =\ logging.Formatter("%(asctime)s [%(process)d]: %(message)s") log_handler.setFormatter(formatter) logger.setLevel(logging.DEBUG) elif verbosity == 1: logger.setLevel(logging.INFO) else: logger.setLevel(logging.WARNING) logger.addHandler(log_handler) self._process_args(options) for backend in backends: r = reconciliation.BackendReconciler(backend=backend, logger=logger, options=options) r.reconcile()
def handle_args(self, *args, **options): if options["suspended"]: self.filters["suspended"] = True if options["backend_id"]: backend = get_backend(options["backend_id"]) self.filters["backend"] = backend.id if options["build"]: self.filters["operstate"] = "BUILD" if options["image_name"]: self.fields = [ "image.name" if x == "image.id" else x for x in self.fields ] if "ipv4" in self.fields or "ipv6" in self.fields: self.prefetch_related.append("nics__ips__subnet")
def handle(self, *args, **options): if args: raise CommandError("Command doesn't accept any arguments") name = options['name'] user_id = options['user_id'] backend_id = options['backend_id'] image_id = options['image_id'] flavor_id = options['flavor_id'] password = options['password'] if not name: raise CommandError("name is mandatory") if not user_id: raise CommandError("user-id is mandatory") if not password: raise CommandError("password is mandatory") if not flavor_id: raise CommandError("flavor-id is mandatory") if not image_id: raise CommandError("image-id is mandatory") flavor = common.get_flavor(flavor_id) image = common.get_image(image_id, user_id) if backend_id: backend = common.get_backend(backend_id) else: backend = None connection_list = parse_connections(options["connections"]) server = servers.create(user_id, name, password, flavor, image, networks=connection_list, use_backend=backend) pprint.pprint_server(server, stdout=self.stdout) wait = parse_bool(options["wait"]) common.wait_server_task(server, wait, self.stdout)
def handle(self, **options): if options["backend_id"]: backends = [get_backend(options["backend_id"])] else: backends = Backend.objects.filter(offline=False) if not options["drained"]: backends = backends.filter(drained=False) now = datetime.datetime.now() if options["older_than"] is not None: minutes = int(options["older_than"]) else: minutes = settings.BACKEND_REFRESH_MIN delta = datetime.timedelta(minutes=minutes) for b in backends: if now > b.updated + delta: update_resources(b) print "Successfully updated backend with id: %d" % b.id else: print "Backend %d does not need update" % b.id
def handle(self, **options): if options['backend_id']: backends = [get_backend(options['backend_id'])] else: backends = Backend.objects.filter(offline=False) if not options['drained']: backends = backends.filter(drained=False) now = datetime.datetime.now() if options['older_than'] is not None: minutes = int(options['older_than']) else: minutes = settings.BACKEND_REFRESH_MIN delta = datetime.timedelta(minutes=minutes) for b in backends: if now > b.updated + delta: update_resources(b) print 'Successfully updated backend with id: %d' % b.id else: print 'Backend %d does not need update' % b.id
def handle(self, *args, **options): if options["backend"] is not None: backend = get_backend(options["backend"]) else: backend = None clusters = parse_bool(options["clusters"]) servers = parse_bool(options["servers"]) resources = parse_bool(options["resources"]) networks = parse_bool(options["networks"]) images = parse_bool(options["images"]) stats = statistics.get_cyclades_stats(backend, clusters, servers, resources, networks, images) output_format = options["output_format"] if output_format == "json": self.stdout.write(json.dumps(stats, indent=4) + "\n") elif output_format == "pretty": pretty_print_stats(stats, self.stdout) else: raise CommandError("Output format '%s' not supported." % output_format)
def handle(self, *args, **options): if len(args) != 1: raise CommandError("Please provide a network ID") network = get_network(args[0]) new_name = options.get("name") if new_name is not None: old_name = network.name network = networks.rename(network, new_name) self.stdout.write("Renamed network '%s' from '%s' to '%s'.\n" % (network, old_name, new_name)) drained = options.get("drained") if drained is not None: drained = parse_bool(drained) network.drained = drained network.save() self.stdout.write("Set network '%s' as drained=%s.\n" % (network, drained)) new_owner = options.get("userid") if new_owner is not None: if "@" in new_owner: raise CommandError("Invalid owner UUID.") old_owner = network.userid network.userid = new_owner network.save() msg = "Changed the owner of network '%s' from '%s' to '%s'.\n" self.stdout.write(msg % (network, old_owner, new_owner)) floating_ip_pool = options["floating_ip_pool"] if floating_ip_pool is not None: floating_ip_pool = parse_bool(floating_ip_pool) if floating_ip_pool is False and network.floating_ip_pool is True: if network.ips.filter(deleted=False, floating_ip=True)\ .exists(): msg = ("Cannot make network a non floating IP pool." " There are still reserved floating IPs.") raise CommandError(msg) network.floating_ip_pool = floating_ip_pool network.save() self.stdout.write("Set network '%s' as floating-ip-pool=%s.\n" % (network, floating_ip_pool)) if floating_ip_pool is True: for backend in Backend.objects.filter(offline=False): bnet, jobs =\ backend_mod.ensure_network_is_active(backend, network.id) if jobs: msg = ("Sent job to create network '%s' in backend" " '%s'\n" % (network, backend)) self.stdout.write(msg) add_reserved_ips = options.get('add_reserved_ips') remove_reserved_ips = options.get('remove_reserved_ips') if add_reserved_ips or remove_reserved_ips: if add_reserved_ips: add_reserved_ips = add_reserved_ips.split(",") for ip in add_reserved_ips: network.reserve_address(ip, external=True) if remove_reserved_ips: remove_reserved_ips = remove_reserved_ips.split(",") for ip in remove_reserved_ips: network.release_address(ip, external=True) add_to_backend = options["add_to_backend"] if add_to_backend is not None: backend = get_backend(add_to_backend) bnet, jobs = backend_mod.ensure_network_is_active(backend, network.id) if jobs: msg = "Sent job to create network '%s' in backend '%s'\n" self.stdout.write(msg % (network, backend)) remove_from_backend = options["remove_from_backend"] if remove_from_backend is not None: backend = get_backend(remove_from_backend) if network.nics.filter(machine__backend=backend, machine__deleted=False).exists(): msg = "Cannot remove. There are still connected VMs to this"\ " network" raise CommandError(msg) backend_mod.delete_network(network, backend, disconnect=True) msg = "Sent job to delete network '%s' from backend '%s'\n" self.stdout.write(msg % (network, backend))
def handle(self, *args, **options): if args: raise CommandError("Command doesn't accept any arguments") dry_run = options["dry_run"] name = options['name'] subnet = options['subnet'] backend_id = options['backend_id'] public = options['public'] flavor = options['flavor'] mode = options['mode'] link = options['link'] mac_prefix = options['mac_prefix'] tags = options['tags'] userid = options["owner"] if not name: raise CommandError("Name is required") if not subnet: raise CommandError("Subnet is required") if not flavor: raise CommandError("Flavor is required") if public and not backend_id: raise CommandError("backend-id is required") if not userid and not public: raise CommandError("'owner' is required for private networks") if mac_prefix and flavor == "MAC_FILTERED": raise CommandError("Can not override MAC_FILTERED mac-prefix") if link and flavor == "PHYSICAL_VLAN": raise CommandError("Can not override PHYSICAL_VLAN link") if backend_id: backend = get_backend(backend_id) fmode, flink, fmac_prefix, ftags = values_from_flavor(flavor) mode = mode or fmode link = link or flink mac_prefix = mac_prefix or fmac_prefix tags = tags or ftags try: validate_mac(mac_prefix + "0:00:00:00") except InvalidMacAddress: raise CommandError("Invalid MAC prefix '%s'" % mac_prefix) subnet, gateway, subnet6, gateway6 = validate_network_info(options) if not link or not mode: raise CommandError("Can not create network." " No connectivity link or mode") netinfo = { "name": name, "userid": options["owner"], "subnet": subnet, "gateway": gateway, "gateway6": gateway6, "subnet6": subnet6, "dhcp": options["dhcp"], "flavor": flavor, "public": public, "mode": mode, "link": link, "mac_prefix": mac_prefix, "tags": tags, "state": "ACTIVE"} if dry_run: self.stdout.write("Creating network:\n") pprint_table(self.stdout, tuple(netinfo.items())) return network = Network.objects.create(**netinfo) if userid: quotas.issue_and_accept_commission(network) if backend_id: # Create BackendNetwork only to the specified Backend network.create_backend_network(backend) create_network(network=network, backend=backend, connect=True)
def handle(self, *args, **options): if args: raise CommandError("Command doesn't accept any arguments") dry_run = options["dry_run"] name = options['name'] subnet = options['subnet'] backend_id = options['backend_id'] public = options['public'] flavor = options['flavor'] mode = options['mode'] link = options['link'] mac_prefix = options['mac_prefix'] tags = options['tags'] userid = options["owner"] if not name: raise CommandError("Name is required") if not subnet: raise CommandError("Subnet is required") if not flavor: raise CommandError("Flavor is required") if public and not backend_id: raise CommandError("backend-id is required") if not userid and not public: raise CommandError("'owner' is required for private networks") if mac_prefix and flavor == "MAC_FILTERED": raise CommandError("Can not override MAC_FILTERED mac-prefix") if link and flavor == "PHYSICAL_VLAN": raise CommandError("Can not override PHYSICAL_VLAN link") if backend_id: backend = get_backend(backend_id) fmode, flink, fmac_prefix, ftags = values_from_flavor(flavor) mode = mode or fmode link = link or flink mac_prefix = mac_prefix or fmac_prefix tags = tags or ftags try: validate_mac(mac_prefix + "0:00:00:00") except InvalidMacAddress: raise CommandError("Invalid MAC prefix '%s'" % mac_prefix) subnet, gateway, subnet6, gateway6 = validate_network_info(options) if not link or not mode: raise CommandError("Can not create network." " No connectivity link or mode") netinfo = { "name": name, "userid": options["owner"], "subnet": subnet, "gateway": gateway, "gateway6": gateway6, "subnet6": subnet6, "dhcp": options["dhcp"], "flavor": flavor, "public": public, "mode": mode, "link": link, "mac_prefix": mac_prefix, "tags": tags, "state": "ACTIVE" } if dry_run: self.stdout.write("Creating network:\n") pprint_table(self.stdout, tuple(netinfo.items())) return network = Network.objects.create(**netinfo) if userid: quotas.issue_and_accept_commission(network) if backend_id: # Create BackendNetwork only to the specified Backend network.create_backend_network(backend) create_network(network=network, backend=backend, connect=True)
def handle(self, **options): verbosity = int(options['verbosity']) self._process_args(options) backend_id = options['backend-id'] backend = get_backend(backend_id) if backend_id else None G, GNics = reconciliation.get_instances_from_ganeti(backend) D = reconciliation.get_servers_from_db(backend) DBNics = reconciliation.get_nics_from_db(backend) # # Detect problems # if options['detect_stale']: stale = reconciliation.stale_servers_in_db(D, G) if len(stale) > 0: print >> sys.stderr, "Found the following stale server IDs: " print " " + "\n ".join([str(x) for x in stale]) elif verbosity == 2: print >> sys.stderr, "Found no stale server IDs in DB." if options['detect_orphans']: orphans = reconciliation.orphan_instances_in_ganeti(D, G) if len(orphans) > 0: print >> sys.stderr, "Found orphan Ganeti instances with IDs: " print " " + "\n ".join([str(x) for x in orphans]) elif verbosity == 2: print >> sys.stderr, "Found no orphan Ganeti instances." if options['detect_unsynced']: unsynced = reconciliation.unsynced_operstate(D, G) if len(unsynced) > 0: print >> sys.stderr, "The operstate of the following server" \ " IDs is out-of-sync:" print " " + "\n ".join([ "%d is %s in DB, %s in Ganeti" % (x[0], x[1], ('UP' if x[2] else 'DOWN')) for x in unsynced ]) elif verbosity == 2: print >> sys.stderr, "The operstate of all servers is in sync." if options['detect_build_errors']: build_errors = reconciliation.instances_with_build_errors(D, G) if len(build_errors) > 0: msg = "The os for the following server IDs was not build"\ " successfully:" print >> sys.stderr, msg print " " + "\n ".join(["%d" % x for x in build_errors]) elif verbosity == 2: print >> sys.stderr, "Found no instances with build errors." if options['detect_unsynced_nics']: def pretty_print_nics(nics): if not nics: print ''.ljust(18) + 'None' for index, info in nics.items(): print ''.ljust(18) + 'nic/' + str(index) +\ ': MAC: %s, IP: %s, Network: %s' % \ (info['mac'], info['ipv4'], info['network']) unsynced_nics = reconciliation.unsynced_nics(DBNics, GNics) if len(unsynced_nics) > 0: msg = "The NICs of the servers with the following IDs are"\ " unsynced:" print >> sys.stderr, msg for id, nics in unsynced_nics.items(): print ''.ljust(2) + '%6d:' % id print ''.ljust(8) + '%8s:' % 'DB' pretty_print_nics(nics[0]) print ''.ljust(8) + '%8s:' % 'Ganeti' pretty_print_nics(nics[1]) elif verbosity == 2: print >> sys.stderr, "All instance nics are synced." # # Then fix them # if options['fix_stale'] and len(stale) > 0: print >> sys.stderr, \ "Simulating successful Ganeti removal for %d " \ "servers in the DB:" % len(stale) for vm in VirtualMachine.objects.filter(pk__in=stale): event_time = datetime.datetime.now() backend_mod.process_op_status( vm=vm, etime=event_time, jobid=-0, opcode='OP_INSTANCE_REMOVE', status='success', logmsg='Reconciliation: simulated Ganeti event') print >> sys.stderr, " ...done" if options['fix_orphans'] and len(orphans) > 0: print >> sys.stderr, \ "Issuing OP_INSTANCE_REMOVE for %d Ganeti instances:" % \ len(orphans) for id in orphans: try: vm = VirtualMachine.objects.get(pk=id) with pooled_rapi_client(vm) as client: client.DeleteInstance(utils.id_to_instance_name(id)) except VirtualMachine.DoesNotExist: print >> sys.stderr, "No entry for VM %d in DB !!" % id print >> sys.stderr, " ...done" if options['fix_unsynced'] and len(unsynced) > 0: print >> sys.stderr, "Setting the state of %d out-of-sync VMs:" % \ len(unsynced) for id, db_state, ganeti_up in unsynced: vm = VirtualMachine.objects.get(pk=id) opcode = "OP_INSTANCE_REBOOT" if ganeti_up \ else "OP_INSTANCE_SHUTDOWN" event_time = datetime.datetime.now() backend_mod.process_op_status( vm=vm, etime=event_time, jobid=-0, opcode=opcode, status='success', logmsg='Reconciliation: simulated Ganeti event') print >> sys.stderr, " ...done" if options['fix_build_errors'] and len(build_errors) > 0: print >> sys.stderr, "Setting the state of %d build-errors VMs:" %\ len(build_errors) for id in build_errors: vm = VirtualMachine.objects.get(pk=id) event_time = datetime.datetime.now() backend_mod.process_op_status( vm=vm, etime=event_time, jobid=-0, opcode="OP_INSTANCE_CREATE", status='error', logmsg='Reconciliation: simulated Ganeti event') print >> sys.stderr, " ...done" if options['fix_unsynced_nics'] and len(unsynced_nics) > 0: print >> sys.stderr, "Setting the nics of %d out-of-sync VMs:" % \ len(unsynced_nics) for id, nics in unsynced_nics.items(): vm = VirtualMachine.objects.get(pk=id) nics = nics[1] # Ganeti nics if nics == {}: # No nics vm.nics.all.delete() continue for index, nic in nics.items(): net_id = utils.id_from_network_name(nic['network']) subnet6 = Network.objects.get(id=net_id).subnet6 # Produce ipv6 ipv6 = subnet6 and mac2eui64(nic['mac'], subnet6) or None nic['ipv6'] = ipv6 # Rename ipv4 to ip nic['ip'] = nic['ipv4'] # Dict to sorted list final_nics = [] nics_keys = nics.keys() nics_keys.sort() for i in nics_keys: if nics[i]['network']: final_nics.append(nics[i]) else: print 'Network of nic %d of vm %s is None. ' \ 'Can not reconcile' % (i, vm.backend_vm_id) event_time = datetime.datetime.now() backend_mod.process_net_status(vm=vm, etime=event_time, nics=final_nics) print >> sys.stderr, " ...done"
def handle(self, **options): verbosity = int(options['verbosity']) self._process_args(options) backend_id = options['backend-id'] backend = get_backend(backend_id) if backend_id else None G, GNics = reconciliation.get_instances_from_ganeti(backend) D = reconciliation.get_servers_from_db(backend) DBNics = reconciliation.get_nics_from_db(backend) # # Detect problems # if options['detect_stale']: stale = reconciliation.stale_servers_in_db(D, G) if len(stale) > 0: print >> sys.stderr, "Found the following stale server IDs: " print " " + "\n ".join( [str(x) for x in stale]) elif verbosity == 2: print >> sys.stderr, "Found no stale server IDs in DB." if options['detect_orphans']: orphans = reconciliation.orphan_instances_in_ganeti(D, G) if len(orphans) > 0: print >> sys.stderr, "Found orphan Ganeti instances with IDs: " print " " + "\n ".join( [str(x) for x in orphans]) elif verbosity == 2: print >> sys.stderr, "Found no orphan Ganeti instances." if options['detect_unsynced']: unsynced = reconciliation.unsynced_operstate(D, G) if len(unsynced) > 0: print >> sys.stderr, "The operstate of the following server" \ " IDs is out-of-sync:" print " " + "\n ".join( ["%d is %s in DB, %s in Ganeti" % (x[0], x[1], ('UP' if x[2] else 'DOWN')) for x in unsynced]) elif verbosity == 2: print >> sys.stderr, "The operstate of all servers is in sync." if options['detect_build_errors']: build_errors = reconciliation.instances_with_build_errors(D, G) if len(build_errors) > 0: msg = "The os for the following server IDs was not build"\ " successfully:" print >> sys.stderr, msg print " " + "\n ".join( ["%d" % x for x in build_errors]) elif verbosity == 2: print >> sys.stderr, "Found no instances with build errors." if options['detect_unsynced_nics']: def pretty_print_nics(nics): if not nics: print ''.ljust(18) + 'None' for index, info in nics.items(): print ''.ljust(18) + 'nic/' + str(index) +\ ': MAC: %s, IP: %s, Network: %s' % \ (info['mac'], info['ipv4'], info['network']) unsynced_nics = reconciliation.unsynced_nics(DBNics, GNics) if len(unsynced_nics) > 0: msg = "The NICs of the servers with the following IDs are"\ " unsynced:" print >> sys.stderr, msg for id, nics in unsynced_nics.items(): print ''.ljust(2) + '%6d:' % id print ''.ljust(8) + '%8s:' % 'DB' pretty_print_nics(nics[0]) print ''.ljust(8) + '%8s:' % 'Ganeti' pretty_print_nics(nics[1]) elif verbosity == 2: print >> sys.stderr, "All instance nics are synced." # # Then fix them # if options['fix_stale'] and len(stale) > 0: print >> sys.stderr, \ "Simulating successful Ganeti removal for %d " \ "servers in the DB:" % len(stale) for vm in VirtualMachine.objects.filter(pk__in=stale): event_time = datetime.datetime.now() backend_mod.process_op_status( vm=vm, etime=event_time, jobid=-0, opcode='OP_INSTANCE_REMOVE', status='success', logmsg='Reconciliation: simulated Ganeti event') print >> sys.stderr, " ...done" if options['fix_orphans'] and len(orphans) > 0: print >> sys.stderr, \ "Issuing OP_INSTANCE_REMOVE for %d Ganeti instances:" % \ len(orphans) for id in orphans: try: vm = VirtualMachine.objects.get(pk=id) with pooled_rapi_client(vm) as client: client.DeleteInstance(utils.id_to_instance_name(id)) except VirtualMachine.DoesNotExist: print >> sys.stderr, "No entry for VM %d in DB !!" % id print >> sys.stderr, " ...done" if options['fix_unsynced'] and len(unsynced) > 0: print >> sys.stderr, "Setting the state of %d out-of-sync VMs:" % \ len(unsynced) for id, db_state, ganeti_up in unsynced: vm = VirtualMachine.objects.get(pk=id) opcode = "OP_INSTANCE_REBOOT" if ganeti_up \ else "OP_INSTANCE_SHUTDOWN" event_time = datetime.datetime.now() backend_mod.process_op_status( vm=vm, etime=event_time, jobid=-0, opcode=opcode, status='success', logmsg='Reconciliation: simulated Ganeti event') print >> sys.stderr, " ...done" if options['fix_build_errors'] and len(build_errors) > 0: print >> sys.stderr, "Setting the state of %d build-errors VMs:" %\ len(build_errors) for id in build_errors: vm = VirtualMachine.objects.get(pk=id) event_time = datetime.datetime.now() backend_mod.process_op_status( vm=vm, etime=event_time, jobid=-0, opcode="OP_INSTANCE_CREATE", status='error', logmsg='Reconciliation: simulated Ganeti event') print >> sys.stderr, " ...done" if options['fix_unsynced_nics'] and len(unsynced_nics) > 0: print >> sys.stderr, "Setting the nics of %d out-of-sync VMs:" % \ len(unsynced_nics) for id, nics in unsynced_nics.items(): vm = VirtualMachine.objects.get(pk=id) nics = nics[1] # Ganeti nics if nics == {}: # No nics vm.nics.all.delete() continue for index, nic in nics.items(): net_id = utils.id_from_network_name(nic['network']) subnet6 = Network.objects.get(id=net_id).subnet6 # Produce ipv6 ipv6 = subnet6 and mac2eui64(nic['mac'], subnet6) or None nic['ipv6'] = ipv6 # Rename ipv4 to ip nic['ip'] = nic['ipv4'] # Dict to sorted list final_nics = [] nics_keys = nics.keys() nics_keys.sort() for i in nics_keys: if nics[i]['network']: final_nics.append(nics[i]) else: print 'Network of nic %d of vm %s is None. ' \ 'Can not reconcile' % (i, vm.backend_vm_id) event_time = datetime.datetime.now() backend_mod.process_net_status(vm=vm, etime=event_time, nics=final_nics) print >> sys.stderr, " ...done"