def capacity_add():
    logger = logging.getLogger(__name__)
    settings = Settings()
    all_routers = get_all_routers()
    form = AddCapacity()

    form.Region.choices = settings.get_regions_tuples()
    form.InstanceType.choices = settings.get_instances_tuples()
    form.instance_number.choices = (('1', '1'), ('2', '2'), ('3', '3'),
                                    ('4', '4'), ('5', '5'), ('6', '6'))
    unique_clusters = get_available_clusters(all_routers)
    cluster_list = []
    for i in unique_clusters:
        cluster_list.append((i, i))
    cluster_list.sort()
    form.cluster_value.choices = cluster_list

    if form.validate_on_submit():
        if form.InstanceType.data not in settings.get_region_supported_instances(
                form.Region.data):
            flash("Instance type '{}' is not available in '{}'".format(
                form.InstanceType.data, form.Region.data))
            return redirect(url_for('capacity_add'))

        cluster_already_there_result = check_router_in_region(
            all_routers, form.cluster_value.data, form.Region.data)
        if not cluster_already_there_result:
            flash("Region '{region}' does not yet contain cluster '{cluster}'."
                  " Maybe you want to extend cluster '{cluster}' into region.".
                  format(region=form.Region.data,
                         cluster=form.cluster_value.data))
            return redirect(url_for('capacity_add'))

        available_dmvpn_addresses = get_available_dmvpn_addresses(
            all_routers, form.cluster_value.data,
            int(form.instance_number.data))
        available_subnets = get_available_vpc_cidr_space(
            all_routers, form.cluster_value.data,
            int(form.instance_number.data))
        az_list = get_best_az(all_routers, form.Region.data,
                              form.cluster_value.data,
                              int(form.instance_number.data))

        hubs = list()
        for rou in all_routers:
            if (rou.cluster_value == form.cluster_value.data) and (rou.hub
                                                                   == 'True'):
                hubs.append(rou)
        cgw_template = hubs[0]
        list_router_objects = list()
        for i in range(int(form.instance_number.data)):
            list_router_objects.append(
                Cgw(Region=form.Region.data,
                    hub=False,
                    region_extension=False,
                    AvailabilityZone=az_list.pop(-1),
                    InstanceType=form.InstanceType.data,
                    asn=int(cgw_template.asn),
                    cluster_value=form.cluster_value.data,
                    available_bandwidth=Settings.instance_types[
                        form.InstanceType.data],
                    AmiId=Settings.regions[form.Region.data]['ami'],
                    max_bandwidth=Settings.instance_types[
                        form.InstanceType.data],
                    KeyName=Settings.regions[form.Region.data]['key'],
                    DmvpnAddress=available_dmvpn_addresses.pop(0),
                    DmvpnNetmask=str(
                        ipaddress.ip_network(
                            Settings.dmvpn_address_space).netmask),
                    eligible='False',
                    DmvpnCidr=Settings.dmvpn_address_space,
                    h1_public=hubs[0].PublicIp,
                    h1_private=hubs[0].DmvpnAddress,
                    h2_public=hubs[1].PublicIp,
                    h2_private=hubs[1].DmvpnAddress,
                    vpc_cidr=available_subnets.pop(0)))
        results_list = setup_capacity_add.main(list_router_objects)

        if not results_list:
            flash("Capacity add failed")
            logger.warning("Capacity add failed")
        else:
            for i in results_list:
                if i.get('success', False):
                    flash("Router '{}' successfully deployed".format(
                        i['success'].PublicIp))
                    logger.info("Router %s deployed successfully!",
                                i['success'].PublicIp)
                    if i['success'].registration_failed:
                        flash(
                            "Router '{}' failed to register with Cisco Smart Licensing"
                            .format(i['success'].PublicIp))
                        logger.info(
                            "Router %s failed to register with Cisco Smart Licensing",
                            i['success'].PublicIp)
                else:
                    flash("Router '{}' failed to deploy".format(
                        i['fail'].PublicIp))
                    logger.warning(
                        "Router %s deployment and configuration failed",
                        i['fail'].PublicIp)

        return redirect(url_for('capacity_add'))
    return render_template('capacity_add.html',
                           title='Add Capacity',
                           form=form)
def csr_redeploy():
    logger = logging.getLogger(__name__)
    all_routers = get_all_routers()
    settings = Settings()
    form = CsrRedeploy()
    form.InstanceType.choices = settings.get_instances_tuples()

    candidates = list()
    for router in all_routers:
        if router.eligible == 'False':
            candidates.append(router)

    candidates = sorted(candidates,
                        key=lambda k: k.cluster_value,
                        reverse=False)

    csr_t = list()
    for i in candidates:
        csr_t.append((i.PublicIp, i.PublicIp))
    form.csr.choices = csr_t

    if form.validate_on_submit():

        csr_ip = form.csr.data
        for router in candidates:
            if router.PublicIp == csr_ip:
                old_cgw = router

        if form.InstanceType.data not in settings.get_region_supported_instances(
                old_cgw.Region):
            flash("Instance type '{}' is not available in '{}'".format(
                form.InstanceType.data, old_cgw.Region))
            return redirect(url_for('csr_redeploy'))

        hubs = list()
        for rou in all_routers:
            if (rou.cluster_value == old_cgw.cluster_value) and (rou.hub
                                                                 == 'True'):
                hubs.append(rou)

        if old_cgw.hub == 'False':
            available_dmvpn_addresses = get_available_dmvpn_addresses(
                all_routers, old_cgw.cluster_value, 1)
            DmvpnAddress = available_dmvpn_addresses.pop(0)
        else:
            DmvpnAddress = old_cgw.DmvpnAddress
        available_subnets = get_available_vpc_cidr_space(
            all_routers, old_cgw.cluster_value, 1)
        new_cgw = Cgw(
            Region=old_cgw.Region,
            AvailabilityZone=old_cgw.AvailabilityZone,
            hub=old_cgw.hub,
            region_extension=old_cgw.region_extension,
            InstanceType=form.InstanceType.data,
            asn=old_cgw.asn,
            cluster_value=old_cgw.cluster_value,
            available_bandwidth=settings.instance_types[
                form.InstanceType.data],
            AmiId=Settings.regions[old_cgw.Region]['ami'],
            max_bandwidth=Settings.instance_types[form.InstanceType.data],
            KeyName=Settings.regions[old_cgw.Region]['key'],
            DmvpnAddress=DmvpnAddress,
            DmvpnNetmask=old_cgw.DmvpnNetmask,
            DmvpnCidr=old_cgw.DmvpnCidr,
            eligible='False',
            h1_public=hubs[0].PublicIp,
            h1_private=hubs[0].DmvpnAddress,
            h2_public=hubs[1].PublicIp,
            h2_private=hubs[1].DmvpnAddress,
            vpc_cidr=available_subnets.pop(0))

        result = setup_redeploy_csr.main(old_cgw, new_cgw)
        # result = False or cgw object
        if not result:
            flash("Redeploy Failed")
            logger.warning("Redeploy Failed")
        else:
            if result.registration_failed:
                flash(
                    "Router '{}' failed to register with Cisco Smart Licensing"
                    .format(result.PublicIp))
                logger.info(
                    "Router %s failed to register with Cisco Smart Licensing",
                    result.PublicIp)
            flash('The redeploy completed!')
            logger.info('The redeploy of router %s successfully completed!',
                        old_cgw.PublicIp)

        return redirect(url_for('csr_redeploy'))
    return render_template('csr_redeploy.html',
                           title='CSR Redeploy',
                           form=form,
                           cgws=candidates)
def add_cluster():
    logger = logging.getLogger(__name__)
    settings = Settings()
    form = AddCluster()
    form.Region.choices = settings.get_regions_tuples()
    form.InstanceType.choices = settings.get_instances_tuples()

    if form.validate_on_submit():
        region_routers_candidate, region_vgws_candidate, region_vpns_candidate, available_clusters, region_tgws_candidate = get_cluster_data(
            form.Region.data)
        if form.cluster_value.data in available_clusters:
            flash("Cluster name '{}' has already been deployed in '{}'".format(
                form.cluster_value.data, form.Region.data))
            return redirect(url_for('add_cluster'))

        if form.InstanceType.data not in settings.get_region_supported_instances(
                form.Region.data):
            flash("Instance type '{}' is not available in '{}'".format(
                form.InstanceType.data, form.Region.data))
            return redirect(url_for('add_cluster'))

        az_names = get_availability_zones_available(form.Region.data)
        all_routers = get_all_routers()
        available_dmvpn_addresses = get_available_dmvpn_addresses_hub(
            all_routers, form.cluster_value.data, 2)
        available_subnets = get_available_vpc_cidr_space(
            all_routers, form.cluster_value.data, 2)

        router1 = Cgw(
            Region=form.Region.data,
            hub=True,
            region_extension=False,
            AvailabilityZone=az_names[0],
            InstanceType=form.InstanceType.data,
            asn=form.asn.data,
            cluster_value=form.cluster_value.data,
            available_bandwidth=Settings.instance_types[
                form.InstanceType.data],
            AmiId=Settings.regions[form.Region.data]['ami'],
            max_bandwidth=Settings.instance_types[form.InstanceType.data],
            KeyName=Settings.regions[form.Region.data]['key'],
            DmvpnAddress=available_dmvpn_addresses[0],
            DmvpnNetmask=str(
                ipaddress.ip_network(Settings.dmvpn_address_space).netmask),
            eligible='False',
            DmvpnCidr=Settings.dmvpn_address_space,
            vpc_cidr=available_subnets[0])
        router2 = Cgw(
            Region=form.Region.data,
            hub=True,
            region_extension=False,
            AvailabilityZone=az_names[1],
            InstanceType=form.InstanceType.data,
            asn=form.asn.data,
            cluster_value=form.cluster_value.data,
            available_bandwidth=Settings.instance_types[
                form.InstanceType.data],
            AmiId=Settings.regions[form.Region.data]['ami'],
            max_bandwidth=Settings.instance_types[form.InstanceType.data],
            KeyName=Settings.regions[form.Region.data]['key'],
            DmvpnAddress=available_dmvpn_addresses[1],
            DmvpnNetmask=str(
                ipaddress.ip_network(Settings.dmvpn_address_space).netmask),
            eligible='False',
            DmvpnCidr=Settings.dmvpn_address_space,
            vpc_cidr=available_subnets[1])

        r1, r2 = setup_add_cluster.main(router1, router2)
        if r1 == 'fail':
            flash("Cluster '{}' deployment and configuration failed".format(
                form.cluster_value.data))
            logger.warning("Cluster %s deployment and configuration failed",
                           form.cluster_value.data)
        elif r1.registration_failed or r2.registration_failed:
            if r1.registration_failed:
                flash(
                    "Router '{}' failed to register with Cisco Smart Licensing"
                    .format(r1.PublicIp))
            if r2.registration_failed:
                flash(
                    "Router '{}' failed to register with Cisco Smart Licensing"
                    .format(r2.PublicIp))
        else:
            flash("Cluster '{}' deployed successfully!".format(
                r1.cluster_value))
            logger.info("Cluster %s deployed successfully!", r1.cluster_value)

        return redirect(url_for('add_cluster'))
    return render_template('add_cluster.html', title='Add Cluster', form=form)