Skip to content

Instantly share code, notes, and snippets.

@reselbob
Last active May 21, 2023 18:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reselbob/e6486fa087418fbc7698f6c11ef52a8f to your computer and use it in GitHub Desktop.
Save reselbob/e6486fa087418fbc7698f6c11ef52a8f to your computer and use it in GitHub Desktop.

The objective of this track is to learn how to inject data dynamically at test time using just-in-time data.

You'll emulate user input that is typically added in a track's challenge manually using a solve script that will be verified later in a check script.

In this first challenge, you're going to get a random word from an online resource and then assign that random word to an environment variable that you'll persist in the /root/.bashrc file. Saving the environment variable to the /root/.bashrc file will makes its value available later on.

The online resource you'll use to get a random word is an API published by https://wordnik.com. You'll need to register to the site and get an API key in order to have the website provide a random word. You'll add the API to the URL that you'll call using a curl command. The command you'll use to get the random word is:

SECRET_MESSAGE=$(curl -s 'https://api.wordnik.com/v4/words.json/randomWord?api_key=<YOUR_API_KEY> | jq -r '.word')

WHERE <YOUR_API_KEY> is the API key generated for you by the wordnik.com website.**

Once a random word is assigned to SECRET_MESSAGE, you'll add the environment variable and its value to the /root/.bashrc script of reuse in a later challenge.


Step 1: Copy the following command into a terminal window substituting the value of your API key assigned by Wordnik for the string <YOUR_API_KEY>. You'll be assigning your API key to an environment variable named MY_KEY_API.

export MY_API_KEY=<YOUR_API_KEY>

Step 2:

Assign a random word to the environment variable named SECRET_MESSAGE using the WordNik API. Use the following command to get the random word and assign it to the environment variable named SECRET_MESSAGE.

SECRET_MESSAGE=$(curl -s https://api.wordnik.com/v4/words.json/randomWord?api_key=$MY_API_KEY | jq -r '.word')

Step 3: Echo the value of SECRET_MESSAGE to make sure you got a valid random word

echo $SECRET_MESSAGE

You'll get output that is a random word, similar to the following:

alphabet
```

---

`Step 4:`  Save the `SECRET_MESSAGE` environment variable and its value to `/root/.bashrc` for persistence and later use

```bash
echo "export SECRET_MESSAGE=${SECRET_MESSAGE}" >> /root/.bashrc
```

**NEXT**: Access the environment variable and its value.
#!/usr/bin/env bash
source /root/.bashrc
set -euxo pipefail
if [[ -z "$SECRET_MESSAGE" ]]; then
fail-message "The required environment variable SECRET_MESSAGE has not been set."
else
echo "Everything is A-OK."
fi
# Echo the secret message so it shows up in the logs
echo SECRET_MESSAGE:$SECRET_MESSAGE
def emailMessage(status) {
mail to: 'tester@example.com',
subject: "Jenkins Pipeline Update - Status: ${status} - ${currentBuild.fullDisplayName} - Status: ${status}",
body: "The Jenkins pipeline has the following status: ${status}. The details of the pipeline run can be found at: ${currentBuild.absoluteUrl}."
}
def validateInstruqtCli(){
echo "Validating Instruqt CLI"
try{
sh '''
instruqt version
'''
}catch(e){
echo "updating Instruqt: " + e.getMessage()
sh '''
sudo instruqt update
'''
}
finally {
echo "No Finally in force"
}
}
node {
stage("Install jq"){
sh 'sudo dnf install jq -y'
/***
If the Jenkins suver is running on Ubuntu use the command
sh 'sudo snapp install jq -y'
***/
}
stage('Installing Instruqt') { // for display purposes
if (fileExists('/usr/local/bin/instruqt')) {
def isRunning = sh(script: "ps -ef | grep /usr/local/bin/instruqt | grep -v grep", returnStatus: true)
if (isRunning == 0) {
// file exists and is not running
} else {
echo "The file - /usr/local/bin/instruqt - is running"
}
} else {
try{
sh '''
curl -L https://github.com/instruqt/cli/releases/download/2057-ea5a24f/instruqt-linux-2057-ea5a24f.zip -o instruqt.zip
unzip -o instruqt.zip
sudo cp instruqt /usr/local/bin
sudo chmod +x /usr/local/bin/instruqt
'''
echo "instruqt is installed"
validateInstruqtCli()
}catch (e) {
emailMessage("INSTRUQT_COPY_FAIL: ${e.getMessage()}")
echo e
cleanWs()
}finally {
echo "No finally required"
}
}
}
stage('Initializing Pipeline Env Vars'){
env.TRACK_SLUG="injecting-data-in-a-solve-file"
env.TOKEN_SUBSTITUTION_STR = "XXXXXXXXX"
env.SOLVE_FILENAME="solve-data-injector"
withCredentials([usernamePassword(credentialsId: 'INSTRUQT_ACCESS_CREDS', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
env.PWD = PASSWORD
env.USR = USERNAME
echo "PWD and USR set"
}
withCredentials([string(credentialsId: 'RESELBOB_INSTRUQT_TOKEN', variable: 'ITOKEN')]) {
env.ITOKEN = ITOKEN
echo "ITOKEN set"
}
withCredentials([string(credentialsId: 'WORDNIK_API_KEY', variable: 'WORDNIK_API_KEY')]) {
env.WORDNIK_API_KEY = WORDNIK_API_KEY
echo "WORDNIK_API_KEY set: $WORDNIK_API_KEY"
}
env.NO_INJECTION_REQUIRED_MSG="No injection into Instruqt required"
}
stage("Injecting data"){
validateInstruqtCli()
if (fileExists(TRACK_SLUG)) {
sh 'rm -rf $TRACK_SLUG'
} else {
echo '$TRACK_SLUG does not exists'
}
sh 'INSTRUQT_TOKEN="$ITOKEN" instruqt track pull cogarttech/$TRACK_SLUG'
dir(env.TRACK_SLUG){
echo env.TRACK_SLUG
env.TRACK_DIR="01-getting-the-random-word"
env.SOURCE_FILE = env.TRACK_DIR + '/' + env.SOLVE_FILENAME
echo "SOURCE_FILE: " + env.SOURCE_FILE
env.BACKUP_FILE = env.SOURCE_FILE + '-bak'
echo "BACKUP_FILE: " + env.BACKUP_FILE
sh "cp $SOURCE_FILE $BACKUP_FILE"
env.TEMP_FILE_CONTENTS = readFile env.SOURCE_FILE
echo "WORDNIK_API_KEY set at injection: " + env.WORDNIK_API_KEY
env.TEMP_FILE_CONTENTS = env.TEMP_FILE_CONTENTS.replaceAll(env.TOKEN_SUBSTITUTION_STR,env.WORDNIK_API_KEY)
writeFile file: env.SOURCE_FILE, text: env.TEMP_FILE_CONTENTS
env.XTMP = readFile env.SOURCE_FILE
try{
sh '''
echo "Pushing altered file"
INSTRUQT_TOKEN="$ITOKEN" instruqt track push
'''
}catch(err){
sh '''
cp $BACKUP_FILE $SOURCE_FILE
INSTRUQT_TOKEN="$ITOKEN" instruqt track push
'''
//echo err
}finally {
echo "No finally in force"
}
}
}
stage("Running Test"){
validateInstruqtCli()
dir(env.TRACK_SLUG){
env.RUN_STATUS="ERROR"
try{
sh 'INSTRUQT_TOKEN="$ITOKEN" instruqt track test cogarttech/$TRACK_SLUG --skip-fail-check'
sh 'echo ${JOB_NAME} + "ran with SUCCESS."'
sh 'echo "Pushing reset file" '
sh 'cp $BACKUP_FILE $SOURCE_FILE'
sh 'INSTRUQT_TOKEN="$ITOKEN" instruqt track push --force'
cleanWs()
}catch(err){
sh 'echo ${JOB_NAME} + "is in ERROR" '
sh 'echo "Pushing reset file due to error" '
sh 'cp $BACKUP_FILE $SOURCE_FILE '
sh 'INSTRUQT_TOKEN="$ITOKEN" instruqt track push --force '
cleanWs()
throw err
}
}
}
}
#!/usr/bin/env bash
set -euxo pipefail
echo "SOLVE FOR DATA INJECTION"
MY_API_KEY=XXXXXXXXX
API_KEY=$MY_API_KEY
echo "API key in instruqt: $API_KEY"
SECRET_MESSAGE=$(curl -s https://api.wordnik.com/v4/words.json/randomWord?api_key=$API_KEY | jq -r '.word')
echo "exporting SECRET_MESSAGE: "$SECRET_MESSAGE
echo "export SECRET_MESSAGE=${SECRET_MESSAGE}" >> /root/.bashrc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment