# Buggy code
def create(vm_):
    """
    Create a single VM from a data dict
    """
    try:
        # Check for required profile parameters before sending any API calls.
        if (
            vm_["profile"]
            and config.is_profile_configured(
                __opts__,
                __active_provider_name__ or "rackspace",
                vm_["profile"],
                vm_=vm_,
            )
            is False
        ):
            return False
    except AttributeError:
        pass

    # Since using "provider: <provider-engine>" is deprecated, alias provider
    # to use driver: "driver: <provider-engine>"
    if "provider" in vm_:
        vm_["driver"] = vm_.pop("provider")

    __utils__["cloud.fire_event"](
        "event",
        "starting create",
        "salt/cloud/{0}/creating".format(vm_["name"]),
        {
            "name": vm_["name"],
            "profile": vm_["profile"],
            "provider": vm_["driver"],
        },
        transport=__opts__["transport"],
    )

    log.info("Creating Cloud VM {0}".format(vm_["name"]))
    conn = get_conn()
    kwargs = {
        "name": vm_["name"],
        "image": get_image(conn, vm_),
        "size": get_size(conn, vm_),
    }

    __utils__["cloud.fire_event"](
        "event",
        "requesting instance",
        "salt/cloud/{0}/requesting".format(vm_["name"]),
        {
            "kwargs": {
                "name": kwargs["name"],
                "image": kwargs["image"].name,
                "size": kwargs["size"].name,
            }
        },
        transport=__opts__["transport"],
    )

    try:
        data = conn.create_node(**kwargs)
    except Exception as exc:
        log.error(
            "Error creating {0} on RACKSPACE\n\n"
            "The following exception was thrown by libcloud when trying to "
            "run the initial deployment: \n{1}".format(vm_["name"], exc),
            # Show the traceback if the debug logging level is enabled
            exc_info_on_loglevel=logging.DEBUG,
        )
        return False

    def __query_node_data(vm_, data):
        running = False
        try:
            node = show_instance(vm_["name"], "action")
            running = node["state"] == NodeState.RUNNING
            log.debug(
                "Loaded node data for {0}:\nname: {1}\nstate: {2}".format(
                    vm_["name"], pprint.pformat(node["name"]), node["state"]
                )
            )
        except Exception as err:
            log.error(
                "Failed to get nodes list: {0}".format(err),
                # Show the traceback if the debug logging level is enabled
                exc_info_on_loglevel=logging.DEBUG,
            )
            # Trigger a failure in the wait for IP function
            return False

        if not running:
            # Still not running, trigger another iteration
            return

        private = node["private_ips"]
        public = node["public_ips"]

        if private and not public:
            log.warn(
                "Private IPs returned, but not public... Checking for misidentified IPs"
            )
            for private_ip in private:
                private_ip = preferred_ip(vm_, [private_ip])
                if salt.utils.cloud.is_public_ip(private_ip):
                    log.warn("{0} is a public IP".format(private_ip))
                    data.public_ips.append(private_ip)
                else:
                    log.warn("{0} is a private IP".format(private_ip))
                    if private_ip not in data.private_ips:
                        data.private_ips.append(private_ip)

            if ssh_interface(vm_) == "private_ips" and data.private_ips:
                return data

        if private:
            data.private_ips = private
            if ssh_interface(vm_) == "private_ips":
                return data

        if public:
            data.public_ips = public
            if ssh_interface(vm_) != "private_ips":
                return data

    try:
        data = salt.utils.cloud.wait_for_ip(
            __query_node_data,
            update_args=(vm_, data),
            timeout=config.get_cloud_config_value(
                "wait_for_ip_timeout", vm_, __opts__, default=25 * 60
            ),
            interval=config.get_cloud_config_value(
                "wait_for_ip_interval", vm_, __opts__, default=10
            ),
        )
    except (SaltCloudExecutionTimeout, SaltCloudExecutionFailure) as exc:
        try:
            # It might be already up, let's destroy it!
            destroy(vm_["name"])
        except SaltCloudSystemExit:
            pass
        finally:
            raise SaltCloudSystemExit(str(exc))

    log.debug("VM is now running")
    if ssh_interface(vm_) == "private_ips":
        ip_address = preferred_ip(vm_, data.private_ips)
    else:
        ip_address = preferred_ip(vm_, data.public_ips)
    log.debug("Using IP address {0}".format(ip_address))

    if salt.utils.cloud.get_salt_interface(vm_, __opts__) == "private_ips":
        salt_ip_address = preferred_ip(vm_, data.private_ips)
        log.info("Salt interface set to: {0}".format(salt_ip_address))
    else:
        salt_ip_address = preferred_ip(vm_, data.public_ips)
        log.debug("Salt interface set to: {0}".format(salt_ip_address))

    if not ip_address:
        raise SaltCloudSystemExit("No IP addresses could be found.")

    vm_["salt_host"] = salt_ip_address
    vm_["ssh_host"] = ip_address
    vm_["password"] = data.extra["password"]

    ret = __utils__["cloud.bootstrap"](vm_, __opts__)

    ret.update(data.__dict__)

    if "password" in data.extra:
        del data.extra["password"]

    log.info("Created Cloud VM '{0[name]}'".format(vm_))
    log.debug(
        "'{0[name]}' VM creation details:\n{1}".format(
            vm_, pprint.pformat(data.__dict__)
        )
    )

    __utils__["cloud.fire_event"](
        "event",
        "created instance",
        "salt/cloud/{0}/created".format(vm_["name"]),
        {
            "name": vm_["name"],
            "profile": vm_["profile"],
            "provider": vm_["driver"],
        },
        transport=__opts__["transport"],
    )

    return ret


# Traceback (TypeError)
'private_ips': ['an:ip:v6', 'an.ip.v4'],
'public_ips': [],
'size': None,
'state': 0}
[WARNING ] Private IPs returned, but not public... Checking for misidentified IPs
[ERROR   ] There was a profile error: argument of type 'bool' is not iterable
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/cloud/cli.py", line 284, in run
self.config.get('names')
File "/usr/lib/python2.7/dist-packages/salt/cloud/__init__.py", line 1458, in run_profile
ret[name] = self.create(vm_)
File "/usr/lib/python2.7/dist-packages/salt/cloud/__init__.py", line 1288, in create
output = self.clouds[func](vm_)
File "/usr/lib/python2.7/dist-packages/salt/cloud/clouds/openstack.py", line 774, in create
'wait_for_ip_interval', vm_, __opts__, default=10),
File "/usr/lib/python2.7/dist-packages/salt/utils/cloud.py", line 2371, in wait_for_ip
data = update_callback(*update_args, **update_kwargs)
File "/usr/lib/python2.7/dist-packages/salt/cloud/clouds/openstack.py", line 730, in __query_node_data
if salt.utils.cloud.is_public_ip(private_ip):
File "/usr/lib/python2.7/dist-packages/salt/utils/cloud.py", line 2266, in is_public_ip
if ':' in ip:
TypeError: argument of type 'bool' is not iterable

# Fixed code
def create(vm_):
    """
    Create a single VM from a data dict
    """
    try:
        # Check for required profile parameters before sending any API calls.
        if (
            vm_["profile"]
            and config.is_profile_configured(
                __opts__,
                __active_provider_name__ or "rackspace",
                vm_["profile"],
                vm_=vm_,
            )
            is False
        ):
            return False
    except AttributeError:
        pass

    # Since using "provider: <provider-engine>" is deprecated, alias provider
    # to use driver: "driver: <provider-engine>"
    if "provider" in vm_:
        vm_["driver"] = vm_.pop("provider")

    __utils__["cloud.fire_event"](
        "event",
        "starting create",
        "salt/cloud/{0}/creating".format(vm_["name"]),
        {
            "name": vm_["name"],
            "profile": vm_["profile"],
            "provider": vm_["driver"],
        },
        transport=__opts__["transport"],
    )

    log.info("Creating Cloud VM {0}".format(vm_["name"]))
    conn = get_conn()
    kwargs = {
        "name": vm_["name"],
        "image": get_image(conn, vm_),
        "size": get_size(conn, vm_),
    }

    __utils__["cloud.fire_event"](
        "event",
        "requesting instance",
        "salt/cloud/{0}/requesting".format(vm_["name"]),
        {
            "kwargs": {
                "name": kwargs["name"],
                "image": kwargs["image"].name,
                "size": kwargs["size"].name,
            }
        },
        transport=__opts__["transport"],
    )

    try:
        data = conn.create_node(**kwargs)
    except Exception as exc:
        log.error(
            "Error creating {0} on RACKSPACE\n\n"
            "The following exception was thrown by libcloud when trying to "
            "run the initial deployment: \n{1}".format(vm_["name"], exc),
            # Show the traceback if the debug logging level is enabled
            exc_info_on_loglevel=logging.DEBUG,
        )
        return False

    def __query_node_data(vm_, data):
        running = False
        try:
            node = show_instance(vm_["name"], "action")
            running = node["state"] == NodeState.RUNNING
            log.debug(
                "Loaded node data for {0}:\nname: {1}\nstate: {2}".format(
                    vm_["name"], pprint.pformat(node["name"]), node["state"]
                )
            )
        except Exception as err:
            log.error(
                "Failed to get nodes list: {0}".format(err),
                # Show the traceback if the debug logging level is enabled
                exc_info_on_loglevel=logging.DEBUG,
            )
            # Trigger a failure in the wait for IP function
            return False

        if not running:
            # Still not running, trigger another iteration
            return

        private = node["private_ips"]
        public = node["public_ips"]

        if private and not public:
            log.warn(
                "Private IPs returned, but not public... Checking for misidentified IPs"
            )
            for private_ip in private:
                private_ip = preferred_ip(vm_, [private_ip])
                if private_ip is False:
                    continue
                if salt.utils.cloud.is_public_ip(private_ip):
                    log.warn("{0} is a public IP".format(private_ip))
                    data.public_ips.append(private_ip)
                else:
                    log.warn("{0} is a private IP".format(private_ip))
                    if private_ip not in data.private_ips:
                        data.private_ips.append(private_ip)

            if ssh_interface(vm_) == "private_ips" and data.private_ips:
                return data

        if private:
            data.private_ips = private
            if ssh_interface(vm_) == "private_ips":
                return data

        if public:
            data.public_ips = public
            if ssh_interface(vm_) != "private_ips":
                return data

    try:
        data = salt.utils.cloud.wait_for_ip(
            __query_node_data,
            update_args=(vm_, data),
            timeout=config.get_cloud_config_value(
                "wait_for_ip_timeout", vm_, __opts__, default=25 * 60
            ),
            interval=config.get_cloud_config_value(
                "wait_for_ip_interval", vm_, __opts__, default=10
            ),
        )
    except (SaltCloudExecutionTimeout, SaltCloudExecutionFailure) as exc:
        try:
            # It might be already up, let's destroy it!
            destroy(vm_["name"])
        except SaltCloudSystemExit:
            pass
        finally:
            raise SaltCloudSystemExit(str(exc))

    log.debug("VM is now running")
    if ssh_interface(vm_) == "private_ips":
        ip_address = preferred_ip(vm_, data.private_ips)
    else:
        ip_address = preferred_ip(vm_, data.public_ips)
    log.debug("Using IP address {0}".format(ip_address))

    if salt.utils.cloud.get_salt_interface(vm_, __opts__) == "private_ips":
        salt_ip_address = preferred_ip(vm_, data.private_ips)
        log.info("Salt interface set to: {0}".format(salt_ip_address))
    else:
        salt_ip_address = preferred_ip(vm_, data.public_ips)
        log.debug("Salt interface set to: {0}".format(salt_ip_address))

    if not ip_address:
        raise SaltCloudSystemExit("No IP addresses could be found.")

    vm_["salt_host"] = salt_ip_address
    vm_["ssh_host"] = ip_address
    vm_["password"] = data.extra["password"]

    ret = __utils__["cloud.bootstrap"](vm_, __opts__)

    ret.update(data.__dict__)

    if "password" in data.extra:
        del data.extra["password"]

    log.info("Created Cloud VM '{0[name]}'".format(vm_))
    log.debug(
        "'{0[name]}' VM creation details:\n{1}".format(
            vm_, pprint.pformat(data.__dict__)
        )
    )

    __utils__["cloud.fire_event"](
        "event",
        "created instance",
        "salt/cloud/{0}/created".format(vm_["name"]),
        {
            "name": vm_["name"],
            "profile": vm_["profile"],
            "provider": vm_["driver"],
        },
        transport=__opts__["transport"],
    )

    return ret