Skip to content

Commit acd58c8

Browse files
authored
Merge pull request #17 from Rathan8/cqlsh-expansion-python3
Cqlsh expansion python3 with Desc functionality for cassandra 3.11
2 parents 1a629de + ead8e25 commit acd58c8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+3790
-2281
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
/cqlsh-expansion/cqlsh_expansion.egg-info
44
/cqlsh-expansion/build
55
/cqlsh-expansion/dist
6+
/cqlsh-expansion/pylib/cqlshlib/__pycache__
67
.idea

Dockerfile

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#Amazon Keyspaces toolkit
22

3-
ARG CLI_VERSION=latest
3+
ARG CLI_VERSION=2.1.27
44
FROM amazon/aws-cli:$CLI_VERSION
55

66
ENV AWS_KEYSPACES_WORKING_DIR=/root
@@ -9,9 +9,26 @@ ENV CQLSHRC_HOME=$AWS_KEYSPACES_WORKING_DIR/.cassandra
99

1010
WORKDIR $AWS_KEYSPACES_WORKING_DIR
1111

12+
#Install python3 and set as python3 simlink
13+
14+
RUN yum install gcc openssl-devel bzip2-devel libffi-devel gzip make tar -y
15+
RUN curl https://www.python.org/ftp/python/3.7.9/Python-3.7.9.tgz --output Python-3.7.9.tgz
16+
RUN tar xzf Python-3.7.9.tgz
17+
WORKDIR $AWS_KEYSPACES_WORKING_DIR/Python-3.7.9
18+
RUN ./configure --enable-optimizations
19+
RUN make altinstall
20+
RUN export PATH=${PATH}:/usr/local/lib/
21+
RUN ln -s /usr/local/bin/python3.7 /usr/bin/python3
22+
WORKDIR $AWS_KEYSPACES_WORKING_DIR
23+
RUN rm -f Python-3.7.9.tgz
24+
1225
#Install jq
1326
RUN yum install -y jq && yum clean all
1427

28+
#set as python3 as default interpreter
29+
RUN unlink /usr/bin/python
30+
RUN ln -s /usr/bin/python3 /usr/bin/python
31+
1532
#setup directory structure
1633
RUN mkdir $CASSANDRA_HOME && \
1734
mkdir $CASSANDRA_HOME/bin && \

bin/aws-sm-cqlsh-expo-backoff.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ backoff=0
2323

2424
trap "echo Exited!; exit;" SIGINT SIGTERM
2525

26-
mysecret=$(aws secretsmanager get-secret-value --secret-id "$1" --query SecretString --output text)
26+
mysecret=$(aws secretsmanager get-secret-value --secret-id "$1" --region "$4" --query SecretString --output text)
2727

2828
username=$(jq --raw-output '.username' <<< $mysecret)
2929
password=$(jq --raw-output '.password' <<< $mysecret)
3030
host=$(jq --raw-output '.host' <<< $mysecret)
3131
port=$(jq --raw-output '.port' <<< $mysecret)
3232

33-
echo "cqlsh $host $port -u **** -p **** ${@:4}"
33+
echo "cqlsh-expansion $host $port -u **** -p **** ${@:5}"
3434

3535
while [ $success -ne 0 -a $attempts -le $3 -a $SECONDS -le $2 ]
3636
do
@@ -43,7 +43,7 @@ while [ $success -ne 0 -a $attempts -le $3 -a $SECONDS -le $2 ]
4343
echo ""
4444

4545
#take paramters starting at $4
46-
cqlsh $host $port -u $username -p $password "${@:4}"
46+
cqlsh-expansion $host $port -u $username -p $password "${@:5}"
4747

4848
success=$?
4949
((attempts++))

bin/aws-sm-cqlsh.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
#$1 secret-id
1515
#$2 CQL statement
1616

17-
mysecret=$(aws secretsmanager get-secret-value --secret-id "$1" --query SecretString --output text)
17+
mysecret=$(aws secretsmanager get-secret-value --secret-id "$1" --region "$2" --query SecretString --output text)
1818

1919
username=$(jq --raw-output '.username' <<< $mysecret)
2020
password=$(jq --raw-output '.password' <<< $mysecret)
2121
host=$(jq --raw-output '.host' <<< $mysecret)
2222
port=$(jq --raw-output '.port' <<< $mysecret)
2323

24-
echo "executing.. cqlsh" $host $port "-u *** -p *** ${@:2}"
25-
cqlsh $host $port -u $username -p $password "${@:2}"
24+
echo "executing.. cqlsh" $host $port "-u *** -p *** ${@:3}"
25+
cqlsh-expansion $host $port -u $username -p $password "${@:3}"

cqlsh-expansion/README.md

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,15 @@ The Amazon Keyspaces toolkit contains common Cassandra tooling and helpers preco
99
To install the cqlsh-expansion python package you can run the following pip command. The command below executes a “pip install” that will install the cqlsh-expansion scripts. It will also install a requirements file containing a list of dependencies. The --`user` flag tells pip to use the Python *user install directory* for your platform. Typically ~/.local/ on unix based systems.
1010

1111
```
12-
1312
pip install --user cqlsh-expansion
14-
1513
```
1614

1715
Alternatively, if you are using python3 as default you may have to use the following command to install the cqlsh-expansion package.
1816

1917
```
20-
21-
python2 -m pip install --user cqlsh-expansion
22-
18+
python3 -m pip install --user cqlsh-expansion
2319
```
2420

25-
26-
2721
## Setup cqlsh-expansion to connect to Amazon Keyspaces
2822

2923
To use the cqlsh-expansion with Amazon Keyspaces you can use the following post install script or by following the instructions found in the official [Amazon Keyspaces documentation.](https://docs.aws.amazon.com/keyspaces/latest/devguide/programmatic.cqlsh.html)
@@ -45,54 +39,64 @@ Now that you have you cqlsh-expansion installed and have setup up the configurat
4539
To connect to Amazon Keyspaces you will need to choose one of the [service endpoints](https://docs.aws.amazon.com/keyspaces/latest/devguide/programmatic.endpoints.html). You can also connect to Amazon Keyspaces using [Interface VPC endpoints](https://docs.aws.amazon.com/keyspaces/latest/devguide/vpc-endpoints.html) to enable private communication between your virtual private cloud (VPC) running in Amazon VPC and Amazon Keyspaces. For example, to connect to the Keyspaces service in US East (N. Virginia) (us-east-1) you will want to use the [cassandra.us-east-1.amazonaws.com](http://cassandra.us-east-1.amazonaws.com/) service endpoint. All communication with Amazon Keyspaces will be over port 9142.
4640

4741
### Choose authentication method and connect
48-
49-
To provide users and applications with credentials for programmatic access to Amazon Keyspaces resources, you can do either of the following:
42+
To provide users and applications with credentials for programmatic access to Amazon Keyspaces resources, you can do either of the following:
5043

5144
#### Connect with IAM access keys (users,roles, and federated identities)
5245

53-
For enhanced security, we recommend to create IAM access keys for IAM users and roles that are used across all AWS services. To use IAM access keys to connect to Amazon Keyspaces, customers can use the Signature Version 4 Process (SigV4) authentication plugin for Cassandra client drivers. To learn more about how the Amazon Keyspaces SigV4 plugin enables [IAM users, roles, and federated identities](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) to authenticate in Amazon Keyspaces API requests, see [AWS Signature Version 4 process (SigV4)](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html). You can use the Sigv4 plugin with the cqlsh-expansion script by providing the following flag. . `--auth-provider "SigV4AuthProvider"` . The Sigv4 plugin depends on the AWS SDK for Python (Boto3) which is included in the requirements file. You will also need to set the the proper credentials to make service calls. You can use the following tutorial to [setup credentials using the AWS CLI.](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html)
46+
For enhanced security, we recommend to create IAM access keys for IAM users and roles that are used across all AWS services. To use IAM access keys to connect to Amazon Keyspaces, customers can use the Signature Version 4 Process (SigV4) authentication plugin for Cassandra client drivers. To learn more about how the Amazon Keyspaces SigV4 plugin enables [IAM users, roles, and federated identities](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) to authenticate in Amazon Keyspaces API requests, see [AWS Signature Version 4 process (SigV4)](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html).
5447

5548
After you have the credentials setup with [privileges](https://docs.aws.amazon.com/keyspaces/latest/devguide/security_iam_service-with-iam.html) to access Amazon Keyspaces system tables, you can execute the following command to connect to Amazon Keyspaces with CQLSH using the Sigv4 process.
5649

57-
```
50+
Validate the module name and classname, region_name based on keyspaces endpoint in cqlshrc file.
5851

59-
cqlsh-expansion cassandra.us-east-1.amazonaws.com 9142 --ssl --auth-provider "SigV4AuthProvider"
52+
```
53+
[auth_provider]
54+
;; you can specify any auth provider found in your python environment
55+
;; module and class will be used to dynamically load the class
56+
;; all other properties found here and in the credentials file under the class name
57+
;; will be passed to the constructor
58+
module = cassandra_sigv4.auth
59+
classname = SigV4AuthProvider
60+
region_name = us-east-1
61+
```
62+
you can also set region as Environment variable
6063

64+
```
65+
export AWS_DEFAULT_REGION = us-east-1
6166
```
6267

68+
To connect to Amazon Keyspaces with cqlsh-expansion using Sigv4 authenticator.
69+
```
70+
cqlsh-expansion cassandra.us-east-1.amazonaws.com
71+
```
6372

6473
#### Connect with service-specific credentials
6574

66-
You can create service-specific credentials that are similar to the traditional username and password that Cassandra uses for authentication and access management. AWS service-specific credentials are associated with a specific AWS Identity and Access Management (IAM) user and can only be used for the service they were created for. For more information, see [Using IAM with Amazon Keyspaces (for Apache Cassandra)](http://using%20iam%20with%20amazon%20keyspaces%20%28for%20apache%20cassandra%29/) in the IAM User Guide. To connect to Amazon Keyspaces using the cqlsh-expansion and IAM service-specific credentials you can use the command below. In this command we are connecting to us-east-1 region with service specific user *‘mike-user-99’ *and service specific user password* ‘user-pass-01’. *You will need to replace these credentials with your own user name and password that were given to you when creating the service specific credentials.
67-
68-
```
75+
You can create service-specific credentials that are similar to the traditional username and password that Cassandra uses for authentication and access management. AWS service-specific credentials are associated with a specific AWS Identity and Access Management (IAM) user and can only be used for the service they were created for. For more information, see [Using IAM with Amazon Keyspaces (for Apache Cassandra)](http://using%20iam%20with%20amazon%20keyspaces%20%28for%20apache%20cassandra%29/) in the IAM User Guide. To connect to Amazon Keyspaces using the cqlsh-expansion and IAM service-specific credentials you can use the command below. In this command we are connecting to us-east-1 region with service specific user *‘Sri-user-99’ *and service specific user password* ‘user-pass-01’. *You will need to replace these credentials with your own user name and password that were given to you when creating the service specific credentials.
6976

70-
cqlsh-expansion cassandra.us-east-1.amazonaws.com 9142 --ssl -u mike-user-99 -p user-pass-01
7177

7278
```
73-
74-
Alternatively, if you want to use the cqlsh without the additional functionality included in the cqlsh-expansion package you can execute the following.
75-
79+
[auth_provider]
80+
;; you can specify any auth provider found in your python environment
81+
;; module and class will be used to dynamically load the class
82+
;; all other properties found here and in the credentials file under the class name
83+
;; will be passed to the constructor
84+
module = cassandra.auth
85+
classname = PlainTextAuthProvider
7686
```
7787

78-
cqlsh cassandra.us-east-1.amazonaws.com 9142 --ssl -u mike-user-99 -p user-pass-01
79-
8088
```
89+
cqlsh-expansion cassandra.us-east-1.amazonaws.com -u Sri-user-99 -p user-pass-01
90+
```
91+
8192

8293
## Cleanup
8394
To remove the cqlsh-expansion package you can use the pip uninstall api. Additionally, if you executed the post install script ```cqlsh-expansion.init```, you may want to delete the .cassandra directory which contains the cqlshrc file and the ssl certificate. Using pip uninstall will not remove changes made by the post install script.
8495

8596
```
8697
pip uninstall cqlsh-expansion
87-
8898
```
8999

90-
## Functional differences from CQLSH
91-
92-
### Sigv4 authentication
93-
94-
Instead of using the service specific credentials for an IAM user, you can use the `--auth-provider "SigV4AuthProvider"` parameter to leverage the Sigv4 authentication plugin for temporary credentials. This plugin enables IAM users, roles, and federated identities to add authentication information to Amazon Keyspaces (for Apache Cassandra) API requests using the AWS Signature Version 4 Process (SigV4). The plugin depends on the AWS SDK for Python (Boto3) and the [Amazon Keyspaces Sigv4 plugin for the DataStax python driver](https://github.com/aws/aws-sigv4-auth-cassandra-python-driver-plugin).
95-
96100
### New output for TTY
97101

98102
When creating a new cqlsh session with the cqlsh-expansion utility, it will show the default consistency level after establishing a new connection. We find customers using cqlsh may not be aware of the default consistency level of `ONE`, and additional transparency will lead to better operational excellence.

cqlsh-expansion/bin/cqlsh

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,85 @@
1515
# See the License for the specific language governing permissions and
1616
# limitations under the License.
1717

18-
# bash code here; finds a suitable python interpreter and execs this file.
19-
# prefer unqualified "python" if suitable:
20-
python -c 'import sys; sys.exit(not (0x020700b0 < sys.hexversion < 0x03000000))' 2>/dev/null \
21-
&& exec python "`python -c "import os;print(os.path.dirname(os.path.realpath('$0')))"`/cqlsh.py" "$@"
22-
for pyver in 2.7; do
23-
which python$pyver > /dev/null 2>&1 && exec python$pyver "`python$pyver -c "import os;print(os.path.dirname(os.path.realpath('$0')))"`/cqlsh.py" "$@"
18+
# shell script to find a suitable Python interpreter and run cqlsh.py
19+
20+
# Use the Python that is specified in the env
21+
if [ -n "$CQLSH_PYTHON" ]; then
22+
USER_SPECIFIED_PYTHON="$CQLSH_PYTHON"
23+
fi
24+
25+
26+
# filter "--python" option and its value, and keep remaining arguments as it is
27+
USER_SPECIFIED_PYTHON_OPTION=false
28+
for arg do
29+
shift
30+
case "$arg" in
31+
--python)
32+
USER_SPECIFIED_PYTHON_OPTION=true
33+
;;
34+
--)
35+
break
36+
;;
37+
*)
38+
if [ "$USER_SPECIFIED_PYTHON_OPTION" = true ] ; then
39+
USER_SPECIFIED_PYTHON_OPTION=false
40+
USER_SPECIFIED_PYTHON="$arg"
41+
else
42+
set -- "$@" "$arg"
43+
fi
44+
;;
45+
esac
2446
done
25-
echo "No appropriate python interpreter found." >&2
47+
48+
if [ "$USER_SPECIFIED_PYTHON_OPTION" = true ] ; then
49+
echo "You must specify a python interpreter path with the --python option"
50+
exit 1
51+
fi
52+
53+
# get a version string for a Python interpreter
54+
get_python_version() {
55+
interpreter=$1
56+
version=$($interpreter -c "import os; print('{}.{}'.format(os.sys.version_info.major, os.sys.version_info.minor))" 2> /dev/null)
57+
echo "$version"
58+
}
59+
60+
# test whether a version string matches one of the supported versions for cqlsh
61+
is_supported_version() {
62+
version=$1
63+
major_version="${version%.*}"
64+
minor_version="${version#*.}"
65+
# python3.6+ is supported
66+
if [ "$major_version" = 3 ] && [ "$minor_version" -ge 6 ]; then
67+
echo "supported"
68+
else
69+
echo "unsupported"
70+
fi
71+
}
72+
73+
run_if_supported_version() {
74+
# get the interpreter and remove it from argument
75+
interpreter="$1" shift
76+
77+
version=$(get_python_version "$interpreter")
78+
if [ -n "$version" ]; then
79+
if [ "$(is_supported_version "$version")" = "supported" ]; then
80+
exec "$interpreter" "$($interpreter -c "import os; print(os.path.dirname(os.path.realpath('$0')))")/cqlsh.py" "$@"
81+
exit
82+
else
83+
echo "Warning: unsupported version of Python:" $version >&2
84+
fi
85+
fi
86+
}
87+
88+
89+
if [ "$USER_SPECIFIED_PYTHON" != "" ]; then
90+
# run a user specified Python interpreter
91+
run_if_supported_version "$USER_SPECIFIED_PYTHON" "$@"
92+
else
93+
for interpreter in python3 python; do
94+
run_if_supported_version "$interpreter" "$@"
95+
done
96+
fi
97+
98+
echo "No appropriate Python interpreter found." >&2
2699
exit 1

cqlsh-expansion/bin/cqlsh-expansion

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,85 @@
1515
# See the License for the specific language governing permissions and
1616
# limitations under the License.
1717

18-
# bash code here; finds a suitable python interpreter and execs this file.
19-
# prefer unqualified "python" if suitable:
20-
python -c 'import sys; sys.exit(not (0x020700b0 < sys.hexversion < 0x03000000))' 2>/dev/null \
21-
&& exec python "`python -c "import os;print(os.path.dirname(os.path.realpath('$0')))"`/cqlsh-expansion.py" "$@"
22-
for pyver in 2.7; do
23-
which python$pyver > /dev/null 2>&1 && exec python$pyver "`python$pyver -c "import os;print(os.path.dirname(os.path.realpath('$0')))"`/cqlsh-expansion.py" "$@"
18+
# shell script to find a suitable Python interpreter and run cqlsh.py
19+
20+
# Use the Python that is specified in the env
21+
if [ -n "$CQLSH_PYTHON" ]; then
22+
USER_SPECIFIED_PYTHON="$CQLSH_PYTHON"
23+
fi
24+
25+
26+
# filter "--python" option and its value, and keep remaining arguments as it is
27+
USER_SPECIFIED_PYTHON_OPTION=false
28+
for arg do
29+
shift
30+
case "$arg" in
31+
--python)
32+
USER_SPECIFIED_PYTHON_OPTION=true
33+
;;
34+
--)
35+
break
36+
;;
37+
*)
38+
if [ "$USER_SPECIFIED_PYTHON_OPTION" = true ] ; then
39+
USER_SPECIFIED_PYTHON_OPTION=false
40+
USER_SPECIFIED_PYTHON="$arg"
41+
else
42+
set -- "$@" "$arg"
43+
fi
44+
;;
45+
esac
2446
done
25-
echo "No appropriate python interpreter found." >&2
47+
48+
if [ "$USER_SPECIFIED_PYTHON_OPTION" = true ] ; then
49+
echo "You must specify a python interpreter path with the --python option"
50+
exit 1
51+
fi
52+
53+
# get a version string for a Python interpreter
54+
get_python_version() {
55+
interpreter=$1
56+
version=$($interpreter -c "import os; print('{}.{}'.format(os.sys.version_info.major, os.sys.version_info.minor))" 2> /dev/null)
57+
echo "$version"
58+
}
59+
60+
# test whether a version string matches one of the supported versions for cqlsh
61+
is_supported_version() {
62+
version=$1
63+
major_version="${version%.*}"
64+
minor_version="${version#*.}"
65+
# python3.6+ is supported
66+
if [ "$major_version" = 3 ] && [ "$minor_version" -ge 6 ]; then
67+
echo "supported"
68+
else
69+
echo "unsupported"
70+
fi
71+
}
72+
73+
run_if_supported_version() {
74+
# get the interpreter and remove it from argument
75+
interpreter="$1" shift
76+
77+
version=$(get_python_version "$interpreter")
78+
if [ -n "$version" ]; then
79+
if [ "$(is_supported_version "$version")" = "supported" ]; then
80+
exec "$interpreter" "$($interpreter -c "import os; print(os.path.dirname(os.path.realpath('$0')))")/cqlsh-expansion.py" "$@"
81+
exit
82+
else
83+
echo "Warning: unsupported version of Python:" $version >&2
84+
fi
85+
fi
86+
}
87+
88+
89+
if [ "$USER_SPECIFIED_PYTHON" != "" ]; then
90+
# run a user specified Python interpreter
91+
run_if_supported_version "$USER_SPECIFIED_PYTHON" "$@"
92+
else
93+
for interpreter in python3 python; do
94+
run_if_supported_version "$interpreter" "$@"
95+
done
96+
fi
97+
98+
echo "No appropriate Python interpreter found." >&2
2699
exit 1

0 commit comments

Comments
 (0)