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)
Example #2
0
    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")
Example #3
0
    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)
Example #4
0
    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):
        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')
Example #6
0
    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')
Example #7
0
    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()
Example #8
0
    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)
Example #9
0
    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()
Example #10
0
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
Example #11
0
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
Example #12
0
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
Example #13
0
    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]
Example #14
0
    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]
Example #15
0
    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")
Example #16
0
    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()
Example #17
0
    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")
Example #18
0
    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)
Example #19
0
    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
Example #20
0
    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
Example #21
0
    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)
Example #22
0
    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))
Example #23
0
    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"
Example #26
0
    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"