# Buggy code
def get_location(conn, vm_):
    """
    Return the node location to use.
    Linode wants a location id, which is an integer, when creating a new VM
    To be flexible, let the user specify any of location id, abbreviation, or
    full name of the location ("Fremont, CA, USA") in the config file)
    """

    locations = avail_locations(conn)
    # Default to Dallas if not otherwise set
    loc = config.get_cloud_config_value("location", vm_, __opts__, default=2)

    # Was this an id that matches something in locations?
    if str(loc) not in [locations[k]["id"] for k in locations]:
        # No, let's try to match it against the full
        # name and the abbreviation and return the id
        for key in locations:
            if str(loc).lower() in (
                key,
                str(locations[key]["id"]).lower(),
                str(locations[key]["abbreviation"]).lower(),
            ):
                return locations[key]["id"]
    else:
        return loc

    # No match.  Return None, cloud provider will
    # use a default or throw an exception
    return None


# Traceback (ApiError)
[DEBUG   ] Sending event - data = {'_stamp': '2015-07-22T15:34:26.638203', 'event': 'requesting instance', 'kwargs': {'name': 'nt-u14-0', 'ex_rsize': 49024, 'image': 124, 'ex_swap': 128, 'ex_private': False, 'size': {'extra': {u'HOURLY': '0.0300', u'DISK': 48, u'PRICE': '20.00', u'RAM': 2048, u'PLANID': 2, u'LABEL': u'Linode 2048', u'AVAIL': {u'10': 500, u'3': 500, u'2': 500, u'4': 500, u'7': 500, u'6': 500, u'9': 500, u'8': 500}, u'CORES': 2, u'XFER': 3000}, 'price': '21.6000', 'ram': 2048, 'bandwidth': 3000, 'disk': 48, 'id': 2}, 'location': None}}
[DEBUG   ] Parameters {'api_key': 'api_key: xxxx REDACTED xxxx', 'api_responseformat': 'json', 'api_action': 'avail.datacenters'}
[DEBUG   ] Raw Response: {"ERRORARRAY":[],"DATA":[{"LOCATION":"Dallas, TX, USA","DATACENTERID":2,"ABBR":"dallas"},{"LOCATION":"Fremont, CA, USA","DATACENTERID":3,"ABBR":"fremont"},{"LOCATION":"Atlanta, GA, USA","DATACENTERID":4,"ABBR":"atlanta"},{"LOCATION":"Newark, NJ, USA","DATACENTERID":6,"ABBR":"newark"},{"LOCATION":"London, England, UK","DATACENTERID":7,"ABBR":"london"},{"LOCATION":"Tokyo, JP","DATACENTERID":8,"ABBR":"tokyo"},{"LOCATION":"Singapore, SG","DATACENTERID":9,"ABBR":"singapore"},{"LOCATION":"Frankfurt, DE","DATACENTERID":10,"ABBR":"frankfurt"}],"ACTION":"avail.datacenters"}
[DEBUG   ] Parameters {'planid': 2, 'datacenterid': None, 'api_responseformat': 'json', 'api_action': 'linode.create', 'api_key': 'api_key: xxxx REDACTED xxxx', 'paymentterm': 1}
[DEBUG   ] Raw Response: {"ERRORARRAY":[{"ERRORCODE":6,"ERRORMESSAGE":"DATACENTERID is required but was not passed in"}],"DATA":{},"ACTION":"linode.create"}
[ERROR   ] Error creating nt-u14-0 on Linode via linode-python

The following exception was thrown by linode-python when trying to run the initial deployment:
[{u'ERRORCODE': 6, u'ERRORMESSAGE': u'DATACENTERID is required but was not passed in'}]
Traceback (most recent call last):
File "/root/SaltStack/salt/salt/cloud/clouds/linode.py", line 921, in create
PlanID=kwargs['size']['extra']['PLANID'], PaymentTerm=1)
File "/usr/local/lib/python2.7/dist-packages/linode/api.py", line 340, in wrapper
return self.__send_request(request)
File "/usr/local/lib/python2.7/dist-packages/linode/api.py", line 294, in __send_request
raise ApiError(s['ERRORARRAY'])
ApiError: [{u'ERRORCODE': 6, u'ERRORMESSAGE': u'DATACENTERID is required but was not passed in'}]
Error: There was a profile error: Failed to deploy VM

# Fixed code
def get_location(conn, vm_):
    """
    Return the node location to use.
    Linode wants a location id, which is an integer, when creating a new VM
    To be flexible, let the user specify any of location id, abbreviation, or
    full name of the location ("Fremont, CA, USA") in the config file)
    """

    locations = avail_locations(conn)
    # Default to Dallas if not otherwise set
    loc = config.get_cloud_config_value("location", vm_, __opts__, default=2)

    # Was this an id that matches something in locations?
    if str(loc) not in [locations[k]["id"] for k in locations]:
        # No, let's try to match it against the full
        # name and the abbreviation and return the id
        for key in locations:
            if str(loc).lower() in (
                str(key).lower(),
                str(locations[key]["id"]).lower(),
                str(locations[key]["abbreviation"]).lower(),
            ):
                return locations[key]["id"]
    else:
        return loc

    # No match. Return default Linode data center location, which is Dallas
    # Dallas is represented by '2' in the Linode API.
    return 2