Linux, Unix and Technology for the mere mortal
Linux, Unix and Technology for the mere mortal

Building the /dev/zero Try Openstack Project

I’ve been obsessed with Openstack for a couple years now because it allows me to build scenarios and learn from them very quickly with very little effort. I’ve always tried to share this with my friends and coworkers so that they too can partake in this accelerated learning experience.

Openstack is all about self service and not having to rely on some external team or person to get things done but I’ve always found the only area where that’s not true is the on boarding or enrolment of Openstack users. There’s no module in the Openstack framework that you can bolt on to handle signup and registration. It’s completely the responsibility of the Openstack owner to do this… in other words. Me.

As a plain old system administrator, I simply don’t have the development skills to code the necessary front end and back end systems needed for the signup and registration pages.

However, I have recently embraced the DevOps mindset and started using tools like Juju, Ansible and Public Cloud services to abstract and automate the build process of my IT systems. By using software to deploy software I’m able to build solutions quickly and sometimes able to make use of technologies that I might not yet have the skills to run or deploy.

So with this in mind I set to see if it was possible to hack up a ‘system’ that would not only fast track the enrolment of my friends into my Openstack Cloud, but give anyone the ability to request access themselves.

Feel free to request access by visting https://try.openstack.devzero.co.za

The first thing I needed was a web form to capture basic information about the user.

I used a platform called Jotform. They’re an online Form Builder and Creator that provide all the tools needed to create web forms and retrieve responses from forms you’ve published… They also have an API!

I figured I could write a script which retrieved the form data using their API and inject that information into Openstack using Ansible’s Openstack modules (os_project, os_quota, os_user).

In reality this was a little more complicated because I use Ansible AWX. This meant that the information coming out of Jotform would need to exist in source control (GitHub) for AWX to read and use it.

So the same script fetching the form data would need to write it out to an Ansible playbook, commit that into GitHub and then AWX would fetch the code and inject the user information to Openstack.

Sweet! This DevOps thing rocks!

It must be said that at no point in the process do I ask the user to create a password. Instead, as part of the playbook generation, my script generates the password for them using a hashing function of certain fields in the form. This way the generated password is unique to each user, but always results in the same string no matter how many times the script runs.

I won’t reveal the actual code but it looks something like this:

echo "  password: $(curl -s -X GET https://api.jotform.com/submission/$SUBMISSIONID?apiKey=$API_AUTHKEY | python3 -m json.tool | grep -e some_unique_data_fields -e some_other_secret_sauce -e '@' | awk  '{print $22,$33,$44,$55}' | tr -d ',' | sha256sum | base64 | tr -d '/') " >> /var/tmp/ansible-openstack/manage_user/vars/main.yml

I now needed to get those credentials back to the user. This is by far not the best or most secure way to do this but I opted for using Sendgrid because they too have an API like Jotform. By using their API, I could get Sendgrid to email the user their credentials on my behalf using the same information the script generated. I simply used curl to POST the desired payload to their API. Sendgrid would then apply that payload to an email template I’d previously composed and send the credentials back to the user.

The fun part was figuring out how not to email users who had already received their credentials (again) everytime a new user signed up.

As part of the script which generated the code to push into GitHub, it also maintained a state file which tracked who had been emailed and who hadn’t. It was a simple solution to a somewhat complicated problem. In plain english it did this:

If email address is missing from state file, add it. If email address column 2 equals yes, then the user has already been emailed, do nothing, else, if email address column 2 equals no, then email them their stuff and update the state file.

The code looks like this:

if [[ -z $(cat /var/tmp/ansible-openstack/scripts/user.state | grep $EMAIL_ADDRESS) ]] 
 then echo $EMAIL_ADDRESS is missing from state file... Adding... ;  echo $EMAIL_ADDRESS,no,no >> /var/tmp/ansible-openstack/scripts/user.state
fi

if [[ $(cat /var/tmp/ansible-openstack/scripts/user.state | grep $EMAIL_ADDRESS | awk -F, '{print $2}') = 'yes' ]] 
 then echo $EMAIL_ADDRESS has already been emailed the credentials... skipping. 
elif [[ $(cat /var/tmp/ansible-openstack/scripts/user.state | grep $EMAIL_ADDRESS | awk -F, '{print $2}') = 'no' ]]
    then $EXECUTE_EMAIL_ACTION
echo $EMAIL_ADDRESS has been emailed their credentials. Will now update state file.
sed -i "s/$(echo $EMAIL_ADDRESS),no,no/$(echo $EMAIL_ADDRESS),yes,no/g" /var/tmp/ansible-openstack/scripts/user.state 
fi

After the user receives the email from Sendgrid, they have everything they need to log into Openstack where they’ll be able to change their password and start playing around with the Cloud on the own personal Openstack Project.

Far from a commercially viable solution but I was pretty impressed with what I was able to achieve using some simple bash scripts, some Ansible and the API of some public cloud services. Let me know what you think in the comments.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 thoughts on “Building the /dev/zero Try Openstack Project”