Fetch the generated database name and substitute using bash - linux

I have a terraform script which installs wordpress automatically. The terraform script runs fine but the issue is with the user data. I want to replace the localhost entry in the wp-config.php file to the rds db instance id. I am passing the file as the user data. Here is the code which i am using.
rds=$(aws rds --region us-east-2 describe-db-instances --query "DBInstances[*].Endpoint.Address" --output text)
cd /var/www/html
cp wp-config-sample.php wp-config.php
sed -i "s/database_name_here/WPTestDevRDS/g" wp-config.php
sed -i "s/username_here/admin/g" wp-config.php
sed -i "s/password_here/Adminhere1234/g" wp-config.php
sed -i "s/localhost/$rds/g" wp-config.php
The user data is getting executed but the issue is i am not able to replace the value of localhost to the value of$rds. The localhost entry is removed but the value of the variable $rds is not getting assigned. I have also tried using ${rds} in sed but it didnt work.Any help in this situation is appreciated.
I am expecting the value of $rds instead of localhost. A sample look of the wp-config.php file
define( 'DB_NAME', 'WPTestDevRDS' );^M
^M
/** Database username */^M
define( 'DB_USER', 'admin' );^M
^M
/** Database password */^M
define( 'DB_PASSWORD', 'Adminhere1234' );^M
^M
/** Database hostname */^M
define( 'DB_HOST', 'localhost' );^M //i need to replace localhost with the value of $rds

Check the variable has the expected value or at least it's not empty
rds=$(aws rds --region us-east-2 describe-db-instances --query "DBInstances[*].Endpoint.Address" --output text)
if [[ -z "$rds" ]]; then
echo "ERROR" >&2
exit 1
fi
...

Related

How to store echo along with its info in the variable in Linux shell script, without losing the echo keyword

I am running a particular mongo command which is not hiding the password in ps for some reason. Upon checking the mongo community they are asking us to hide the password on ps by sending the password as an input via echo command
Example
echo mypassword | usr/bin/mongostat --quiet -u readonly --authenticationDatabase admin
Now this works fine as long as the echo password is used at the start of the mongostat command, but the problem comes in when I store this entire value as a string in a variable
password="pass#123"
mongo_command="echo $password | usr/bin/mongostat --quiet -u readonly --authenticationDatabase admin"
$mongo_command
So when I execute the above script the output is coming as follows
pass#123 | /usr/bin/mongostat --quiet -u readonly --authenticationDatabase admin
It is ignoring the echo keyword and only sending the password when the $mongo_command is executed. So how can I avoid this and ensure that echo goes along with the password, then followed by the pipe (|) symbol to the mongo command so that it looks as shown below
echo Csco#123 | /usr/bin/mongostat --quiet -u readonly --authenticationDatabase admin
Enter password:
insert query update delete getmore command flushes mapped vsize res faults qrw arw net_in net_out conn set repl time
Thanks

Reading and creating Username and passsword from CSV File in ubuntu

line=0
cat userDetails.csv |while IFS="," read -r last first grps
do
line=$((line+1))
if [ $line == 1 ]; then
continue
fi
first=echo "$first"|tr 'A-Z' 'a-z'
last=echo "$last"|tr 'A-Z' 'a-z'
grps=echo "$grps"
for groupName in echo $grps
do
ret=getent group $groupName
if [ -z $ret ]
then
groupadd $groupName
fi
done
passwd=cat /dev/urandom | tr -dc 'a-zA-Z0-9'|head -c10
user1=echo "$last"|tail -c6
user2=echo "$first"|head -c2
grps=echo "$grps"
if [ ! -z $grps]
then
useradd -G $grps $user1$user2 -p $password
else
useradd $user1$user2 -p $password
fi
echo “user id for $first is: $user1$user2, password: $password”
done
This is the code that is reading the CSV file and creating the password, when I run it against the csv File that looks a little like
Smith, John
Doe, Jane
etc.. And the errors coming out are this
./adduser3.sh: line 9: John: command not found
./adduser3.sh: line 10: Smith: command not found
./adduser3.sh: line 11: : command not found
./adduser3.sh: line 14: group: command not found
groupadd: group 'echo' already exists
./adduser3.sh: line 20: /dev/urandom: Permission denied
./adduser3.sh: line 21: Smith: command not found
./adduser3.sh: line 22: John: command not found
./adduser3.sh: line 23: : command not found
useradd: option requires an argument -- 'p'
Usage: useradd [options] LOGIN
useradd -D
useradd -D [options]
Options:
-b, --base-dir BASE_DIR base directory for the home directory of the
new account
-c, --comment COMMENT GECOS field of the new account
-d, --home-dir HOME_DIR home directory of the new account
-D, --defaults print or change default useradd configuration
-e, --expiredate EXPIRE_DATE expiration date of the new account
-f, --inactive INACTIVE password inactivity period of the new account
-g, --gid GROUP name or ID of the primary group of the new
account
-G, --groups GROUPS list of supplementary groups of the new
account
-h, --help display this help message and exit
-k, --skel SKEL_DIR use this alternative skeleton directory
-K, --key KEY=VALUE override /etc/login.defs defaults
-l, --no-log-init do not add the user to the lastlog and
faillog databases
-m, --create-home create the user's home directory
-M, --no-create-home do not create the user's home directory
-N, --no-user-group do not create a group with the same name as
the user
-o, --non-unique allow to create users with duplicate
(non-unique) UID
-p, --password PASSWORD encrypted password of the new account
-r, --system create a system account
-R, --root CHROOT_DIR directory to chroot into
-s, --shell SHELL login shell of the new account
-u, --uid UID user ID of the new account
-U, --user-group create a group with the same name as the user
-Z, --selinux-user SEUSER use a specific SEUSER for the SELinux user mapping
--extrausers Use the extra users database
I cannot figure as to why the dev/urandom permission is messing up with the cat and why it is spitting out the errors it is giving me
The first problem is first=echo "$first" not doing what you think.
To define a variable, you need var=val, with no spaces in val (or you need to quote it). There is also var=val command syntax, where var is defined in a sub-environment created to run command (i.e. temporarily, just for command sake). This is what your command does: first it expands $first to John, then you have the command first=echo John, which defines a variable first with value echo for the duration of the command John. And as the error informs you, there is no command John.
The correct syntax would be first=$(echo $first), which runs the command echo $first and assigns its value to first. Or first="$first", which just assigns the value of first to first. Which makes it very obvious that you are doing something completely unnecessary in the first place.
The rest of the code is peppered with the same kind of error, using echo unnecessarily, wrongly, or both, or failing to quote properly. You should also make sure to indent your code correctly in the future, both for the benefit of the potential answerers, and also for your own sanity when debugging.

docker container - ssh adduser passwd

I've built a script "createcontainer.sh" to automatically create a container. I call the script as follows:
./createdocker.sh newuser newpass
Internal to the script, the two arguments are assigned to variables as follows:
USERNAME=$1 <-- thus USERNAME=newuser
PASSWORD=$2 <-- thus PASSWORD=newpass
The goal is to create the container (this works), log into it with "root/originalpassword" combination I created in the original image (this works), then add "newuser/newpass" credentials which can then be used to access the container via SSH (this appears to work but doesn't actually work).
Inside createdocker.sh is the following line:
/usr/bin/sshpass -p $ORIGINALPASSWORD ssh -p $PORT -o StrictHostKeyChecking=no root#$IP $SCRIPT
What this does is tell the "createcontainer.sh" script to log into the $IP of the container on $PORT with root and $ORIGINALPASSWORD, automatically accept the SSH host key, then execute $SCRIPT which is defined as follows:
SCRIPT="adduser $USERNAME;\ <-- add newuser
echo -e $PASSWORD\n$PASSWORD | (passwd --stdin $USERNAME);\ <-- set newpass
echo ssh username: $USERNAME;\
echo ssh password: $PASSWORD;\
echo Instance Login Success;\
exit"
As a result, the behavior of my script is as follows:
[root#netunique docker-sshd]# ./signup_createdocker.sh newuser newpass
Instance Created
adduser newuser;echo -e newpass\nnewpass | (passwd --stdin newuser);echo ssh username: newuser;echo ssh password: newpass;echo Instance Login Success;exit
Warning: Permanently added '[localhost]:32936' (RSA) to the list of known hosts.
Changing password for user newuser.
passwd: all authentication tokens updated successfully. <-- appears 'set newpass' worked
ssh username: newuser
ssh password: newpass
Instance Login Success
I then attempt to log into the container with the new credentials:
[root#netunique docker-sshd]# ssh -p 32936 newuser#localhost
myuser#localhost's password: <-- here I type 'newpass'
Permission denied, please try again. <-- here the login fails
myuser#localhost's password:
I think my problem has to do with my quotes (") and evaluation of variables within those quotes. Specifically the in SCRIPT which starts with "echo -e".
If I actually (without the script) log into the container manually and issue the following commands, everything works fine. I'm able to log out of the container than back in with newuser/newpass credentials and I can get into the container just fine.
adduser newuser
echo -e "newpass\nnewpass" | (passwd --stdin newuser)
Notice above though that newpass\nnewpass are surrounded in quotes (") whereas in SCRIPT the entire string is surrounded in quotes ("), not specifically the echo -e statement. If anyone can advise how to fix this, it would help me out a lot. Thanks in advance for the help.
BEFORE
SCRIPT="adduser $USERNAME;\ <-- add newuser
echo -e $PASSWORD\n$PASSWORD | (passwd --stdin $USERNAME);\ <-- set newpass
echo ssh username: $USERNAME;\
echo ssh password: $PASSWORD;\
echo Instance Login Success;\
exit"
AFTER
SCRIPT="adduser $USERNAME;\
echo -e \"$PASSWORD\n$PASSWORD\" | (passwd --stdin $USERNAME);\
echo ssh username: $USERNAME;\
echo ssh password: $PASSWORD;\
echo Instance Login Success;\
exit"
I had to include quotes (") around $PASSWORD\n$PASSWORD (which I had previously tried), but I also had to escape them with blackslash (\) like this: \"

Replace Amazon EC2 SSH hostnames (text file) from terminal output

I have deployed an Amazon EC2 cluster of 3 Ubuntu machines (2 of them make up the cluster and the last one is just a client who submits jobs and manages their storage). I connect to all of them via password-less SSH.
What happens is that every time I restart these machines they get new public hostnames from Amazon which I want to replace in my SSH configuration file located in ~/.ssh/config
So far, I figured out a way to get their names and hostnames using Amazon CLI with the following command at my local machine (CentOS 7):
aws ec2 describe-instances --query "Reservations[*].Instances[*].[PublicDnsName,Tags]" --output=text | grep -vwE "None"
This prints something like
ec2-XX-XX-XXX-XXX.us-east-2.compute.amazonaws.com
Name datanode1
ec2-YY-YY-YYY-YYY.us-east-2.compute.amazonaws.com
Name namenode
ec2-ZZ-ZZ-ZZZ-ZZZ.us-east-2.compute.amazonaws.com
Name client
i.e. the hostname, a new line, the corresponding name and so on. The IP fields above like XX-XX-XXX-XXX and so on, are basically 4 hyphen separated numbers of 2 or 3 digits. The grep command I have simply removes the last useless line. Now I want to find a way to replace these hostnames to the SSH configuration file or maybe regenerate it, which looks like
Host namenode
HostName ec2-YY-YY-YYY-YYY.us-east-2.compute.amazonaws.com
User ubuntu
IdentityFile ~/.ssh/mykey.pem
Host datanode1
HostName ec2-XX-XX-XXX-XX.us-east-2.compute.amazonaws.com
User ubuntu
IdentityFile ~/.ssh/mykey.pem
Host client
HostName ec2-ZZ-ZZ-ZZZ-ZZZ.us-east-2.compute.amazonaws.com
User ubuntu
IdentityFile ~/.ssh/mykey.pem
Please note that I don't know how the Amazon CLI command sorts the output. But of course, I can change the order of the machines in my SSH file or maybe it is a good idea to delete it and recreate it.
Below is what I finally figured out and it works. This is Bash script you can just save as .sh file like script.sh and execute. If it can't run simply do chmod +x script.sh. I have added comments to clarify what I am doing.
#Ask Amazon CLI for your hostnames, remove the last line, replace the "Name\t" with "", combine every 2 consecutive lines and save to a txt file
aws ec2 describe-instances --query "Reservations[*].Instances[*].[PublicDnsName,Tags]" --output=text | grep -vwE "None" | sed 's/Name\t//g' | sed 'N;s/\n/ /' > 'ec2instances.txt';
#Change the following variables based on your cluster
publicKey="mykey.pem";
username="ubuntu";
#Remove any preexisting SSH configuration file
rm config
touch config
while read line
do
#Read the line, keep the 1st word and save it as the public DNS
publicDns=$(echo "$line" | cut -d " " -f1);
#Read the line, keep the 2nd word and save it as the hostname you will be using locally to connect to your Amazon EC2
instanceHostname=$(echo "$line" | cut -d " " -f2);
#OK, we are now ready to store to SSH known hosts
sshEntry="Host $instanceHostname\n";
sshEntry="$sshEntry HostName $publicDns\n";
sshEntry="$sshEntry User $username\n";
sshEntry="$sshEntry IdentityFile ~/.ssh/$publicKey\n";
#Attach to the EOF, '-e' enables interpretation of backslash escapes
echo -e "$sshEntry" >> config
#Below is the txt file you will be traversing in the loop
done < ec2instances.txt
#Done
rm ~/.ssh/config
mv config ~/.ssh/config
rm ec2instances.txt

using ldapsearch to return only a value

using an OPENLDAP server i want to retrieve informations from it with ldapsearch. I created a custom class called iduriclass, this class is used to store an id and an uri. in my ldapsearch command i want it to return only the uri for a specified id.
EXAMPLE : the directory contain now two entries id=test uri=server.com/test and id=test2 uri=server.com/test2
Trying it i get an ldif file that contains all uris in the server
I want to have an ldapsearch command that takes test as argument and returns only a value that is : server.com/test
Here's how you query your ldap server.
HOSTNAME=<your ladap hostname>
USERNAME=<your ldap username>
PASSWORD=<your ldap username's password>
SEARCHBASE=<your ldap's search base DN>
QUERYSTRING=test1
PORT=<your ldap port>
ldapsearch -LLL -h ${HOSTNAME} -p $PORT -D cn=${USERNAME} -w ${PASSWORD} -b "${SEARCHBASE}" "(id=${QUERYSTRING})" uri | sed -n 's/^[ \t]*uri:[ \t]*\(.*\)/\1/p'
The option -LLL will not print ldap comments on output. Your ldap may require -x (simple authentication) if it doesn't support SASL.
Adding the parameter -tt writes a file with ONLY the requested attribute(s) value as the OP requested. No preceding field name or anything else. Path is configurable with -T, otherwise is /tmp

Resources