Create a new keyspace in Cassandra.

    :param keyspace:                The keyspace name
    :type  keyspace:                str
    :param replication_strategy:    either `SimpleStrategy` or `NetworkTopologyStrategy`
    :type  replication_strategy:    str
    :param replication_factor:      number of replicas of data on multiple nodes. not used if using NetworkTopologyStrategy
    :type  replication_factor:      int
    :param replication_datacenters: string or dict of datacenter names to replication factors, required if using
                                    NetworkTopologyStrategy (will be a dict if coming from state file).
    :type  replication_datacenters: str | dict[str, int]
    :param contact_points:          The Cassandra cluster addresses, can either be a string or a list of IPs.
    :type  contact_points:          str | list[str]
    :param cql_user:                The Cassandra user if authentication is turned on.
    :type  cql_user:                str
    :param cql_pass:                The Cassandra user password if authentication is turned on.
    :type  cql_pass:                str
    :param port:                    The Cassandra cluster port, defaults to None.
    :type  port:                    int
    :return:                        The info for the keyspace or False if it does not exist.
    :rtype:                         dict

    CLI Example:

    .. code-block:: bash

        # CLI Example:
        salt 'minion1' cassandra_cql.create_keyspace keyspace=newkeyspace

        salt 'minion1' cassandra_cql.create_keyspace keyspace=newkeyspace replication_strategy=NetworkTopologyStrategy \
        replication_datacenters='{"datacenter_1": 3, "datacenter_2": 2}'

def create_keyspace(keyspace, replication_strategy='SimpleStrategy', replication_factor=1, replication_datacenters=None,
                    contact_points=None, port=None, cql_user=None, cql_pass=None):
    '''
    Create a new keyspace in Cassandra.

    :param keyspace:                The keyspace name
    :type  keyspace:                str
    :param replication_strategy:    either `SimpleStrategy` or `NetworkTopologyStrategy`
    :type  replication_strategy:    str
    :param replication_factor:      number of replicas of data on multiple nodes. not used if using NetworkTopologyStrategy
    :type  replication_factor:      int
    :param replication_datacenters: string or dict of datacenter names to replication factors, required if using
                                    NetworkTopologyStrategy (will be a dict if coming from state file).
    :type  replication_datacenters: str | dict[str, int]
    :param contact_points:          The Cassandra cluster addresses, can either be a string or a list of IPs.
    :type  contact_points:          str | list[str]
    :param cql_user:                The Cassandra user if authentication is turned on.
    :type  cql_user:                str
    :param cql_pass:                The Cassandra user password if authentication is turned on.
    :type  cql_pass:                str
    :param port:                    The Cassandra cluster port, defaults to None.
    :type  port:                    int
    :return:                        The info for the keyspace or False if it does not exist.
    :rtype:                         dict

    CLI Example:

    .. code-block:: bash

        # CLI Example:
        salt 'minion1' cassandra_cql.create_keyspace keyspace=newkeyspace

        salt 'minion1' cassandra_cql.create_keyspace keyspace=newkeyspace replication_strategy=NetworkTopologyStrategy \
        replication_datacenters='{"datacenter_1": 3, "datacenter_2": 2}'
    '''
    existing_keyspace = keyspace_exists(keyspace, contact_points, port)
    if not existing_keyspace:
        # Add the strategy, replication_factor, etc.
        replication_map = {
            'class': replication_strategy
        }

        if replication_datacenters:
            if isinstance(replication_datacenters, six.string_types):
                try:
                    replication_datacenter_map = salt.utils.json.loads(replication_datacenters)
                    replication_map.update(**replication_datacenter_map)
                except BaseException:  # pylint: disable=W0703
                    log.error("Could not load json replication_datacenters.")
                    return False
            else:
                replication_map.update(**replication_datacenters)
        else:
            replication_map['replication_factor'] = replication_factor

        query = '''create keyspace {0}
                     with replication = {1}
                      and durable_writes = true;'''.format(keyspace, replication_map)

        try:
            cql_query(query, contact_points, port, cql_user, cql_pass)
        except CommandExecutionError:
            log.critical('Could not create keyspace.')
            raise
        except BaseException as e:
            log.critical('Unexpected error while creating keyspace: %s', e)
            raise